fangpsh's blog

TLS Record Size 优化笔记

从淘宝说起

《淘宝全站HTTPS实践》开始说:

taobao-https

怎么优化呢,调大还是调小。
视频:17min分钟左右:

提到Google 动态调,然后一般设置4k,恩,到底怎样。

看看野狗的文章《扒一扒HTTPS网站的内幕》

TLS Record Size
服务器在建立TLS连接时,会为每个连接分配Buffer,这个Buffer叫TLS Record Size。这个Size是可调。

Size值如果过小,头部负载比重就会过大,最高可达6%。

Size值如果过大,那单个Record在TCP层会被分成多个包发送。浏览器必须等待这些全部达到后,才能解密,一旦出现丢包、拥塞、重传、甚至重新建立的情况,时延就会被相应增加。

那TLS Record Size值如何选择呢?有两个参数可参考。

首先,TLS Record Size要大于证书链和OCSP Stapling响应大小,证书链不会分成多个record;

其次,要小于初始拥塞窗口值,保证服务器在通信之初可以发送足够数据而不需要等待浏览器确认

一般来说,从根CA机构申请的证书为2-3KB左右,级数越多,证书链越大,ocsp响应为2KB左右,所以TLS Record Size是需要根据你的实际情况设置,Google的值5KB。WildDog当前的值是6KB。

看下大神怎么说:《Optimizing TLS Record Size & Buffering Latency》,有详细的介绍,TLS Record过大和过小的缺点。

Nginx 在1.5.9 之后加了ssl_buffer_size,不用硬改源代码了:

Syntax:    ssl_buffer_size size;
Default:
ssl_buffer_size 16k;
Context:    http, server
This directive appeared in version 1.5.9.
Sets the size of the buffer used for sending data.

By default, the buffer size is 16k, which corresponds to minimal overhead when sending big responses. To minimize Time To First Byte it may be beneficial to use smaller values, for example:
   ssl_buffer_size 4k;

大神的一个issue:
https://github.com/nodejs/node-v0.x-archive/issues/6889

That said, exposing a config flag to set a smaller / static record size is also suboptimal as it introduces an inherent tradeoff between latency and throughput – smaller records are good for latency, but hurt server throughput by adding bytes and CPU overhead. It would be great if we could implement a smarter strategy in node... Some background on how Google servers handle this:

new connections default to small record size
      each record fits into a TCP packet
      packets are flushed at record boundaries
server tracks number of bytes written since reset and timestamp of last write
      if bytes written > {configurable byte threshold) then boost record size to 16KB
      if last write timestamp > now - {configurable time threshold} then reset sent byte count

In other words, start with small record size to optimize for delivery of
small/interactive objects (bulk of HTTP traffic). Then, if large file is
being transferred bump record size to 16KB and continue using that until
the connection goes idle.. when communication resumes, start with small
record size and repeat. Overall, this is aimed to optimize delivery of
small files where incremental delivery is a priority, and also for large
downloads where overall throughput is a priority.

恩,不能一味的设置那么小,要动态。

看下书《 HTTPS 权威指南》

16.17 TLS 缓冲区调优
从1.5.9版本开始,Nginx允许使用ssl_buffer_size指令自定义TLS缓冲区的大小。默认值是 16 KB,但是这个值不一定是最优化的,尤其是你希望首字节数据被尽早发送时,有报告显示使 用1400字节的配置可以显著减少延迟。
# 减少TLS缓冲区大小,可以显著减少首字节时间 ssl_buffer_size 1400;
需要注意的是,减少TLS缓冲区大小有可能会降低连接的吞吐量,特别是当你需要发送大量 的数据时。

继续看下Nginx邮件组的讨论:
http://mailman.nginx.org/pipermail/nginx/2013-December/041556.html

最后是cloudflare的:Dynamic TLS Records in NGINX:
Optimizing TLS over TCP to reduce latency,
相关的Nginx Patch: nginx__dynamic_tls_records.patch

结论

直接用cloudflare 的patch;
如果做不到动态,先适当调小。