如何动态调节 TLS Record Size 来减少网络传输延迟?

前言

在前面的章节里面,我们介绍了如何通过优化 HTTPS 来降低网络延迟,这些技术包括:

 – 分布式 Session 复用
 – OCSP Stapling
 – HSTS
 – HTTP/2
 – False Start
 – ChaCha20-Poly1305 算法

经过调研,我们发现 TLS Record Size 大小会对互联网资源内容加载时间产生很大影响;事实上,在比较槽糕的网络环境下,它可以延迟接收数据的处理时长达几次往返;甚至在移动网络上,这可能会导致数百毫秒的不必要的延迟。今天我们将会从 TCP 协议层面来介绍如何通过动态调节 TLS Record Size 来减少网络传输延迟。

TLS 和 TCP

TLS 协议由记录层(TLS Record Layer)和握手层(TLS Handshake Layer)组成,记录层处于协议的最底层,为 TLS 协议提供安全可靠的连接,为高层协议提供数据封装、压缩、加密等基本功能的支持。握手层协议处于记录层协议之上,握手层协议的作用是在真正的应用数据传输之前,使客户端和服务器互相进行身份认证,协商加密算法以及生成加密密钥。其中:

 – 最大的 TLS  Record 的大小为 16KB;
 – 每个 TLS Record 包含一个 5Byte 的头部;

TCP(Transmission Control Protocol 传输控制协议)是一种面向连接(连接导向)的、可靠的、 基于 IP 的传输层协议。

我们知道,TLS 是建立在可靠的数据传输的基础之上,运行在 TCP 层之上,一个 TLS Record Size 由多个 TCP 包组成,通过 WireShark  抓包可以得知:一个 TLS Record 大小为 16408 Byte ,被分为了 12 TCP 包。

△  WireShark 抓包

遇到的问题

我们知道,Nginx 默认的 ssl_buffer_size 大小为 16KB(不支持动态调整),也即一个 TLS Record Size 的大小,举个例子:
假如资源文件的大小为 1600KB,那么就会被拆分为 100 个 TLS Record 传送到客户端。此时会出现这样的问题:

1)TLS Record Size 越大,被拆分的 TCP 包会过多,在传输过程中,如果 TCP 出现丢包情况,那么 TLS Record 到达客户端的时间就会变长,客户端必须等到收到完整的 TLS Record 才能够进行解密,如下图所示:20KB 的资源文件,被分成了大小不同的 record 。TLS Record 及 TCP 包的关系如下图所示:

图片来源:igvita.com 

2)如果 TLS Record Size 较小,则 TCP 丢包对 TLS Record 的影响就较小了,但是于此同时,TLS Record 头部就变多了,可能还会降低连接的吞吐量。

所以,小的 Record Size 会产生额外的消耗;大的 Record Size 会导致延迟;所以可以根据 TCP 窗口大小来合理调整 TLS Record 大小是明智之举。

解决方案

根据以上的的论点,我们可以得出这样的结论:在 TCP 慢启动的过程中,我们可以将 TLS Record Size 调整小点;因为这个过程中 TCP 链接的拥塞窗口(cwnd )较小,TCP 链接的吞吐量也较小;在 TCP 连接结束慢启动之后,TLS Record 的大小可以增大一些,随着时间的推移,最终将 TLS Record 的大小调整到最大(也即 16KB)。

大致的算法规则为:

1)在新连接以及 TCP 慢启动阶段,将 TLS Record 大小调整为大约 1 个 TCP 包的大小;

2)在一定的阶段,也即发送一定数量的 Record Size 之后,采用较大的 Record Size ;

3)随着时间的推移,采用最大的 Record Size 大小,也即 16KB。

为了验证这个过程,通过 WireShark 抓包进行了测试:

阶段一:在刚开始,TLS Record Size 为 1393 Byte 

阶段二:一段时间之后,TLS Record Size 为 4253 Byte

阶段三:最后,TLS Record Size 动态变为 16408 Byte

通过抓包显示,也验证了上面的算法规则;

结语

动态 TLS Record Size 调整是我们 HTTPS 优化过程中的一项关键技术,并且该特性我们针对平台所有的 HTTPS 加速服务都默认开启了。我们还会不断优化和升级 HTTPS 加速,致力于提供更快更安全的 HTTPS 加速解决方案,欢迎您的试用。

参考文档

https://www.igvita.com/2013/12/16/optimizing-nginx-tls-time-to-first-byte/

https://hpbn.co/building-blocks-of-tcp/

https://hpbn.co/transport-layer-security-tls/

https://www.igvita.com/2013/10/24/optimizing-tls-record-size-and-buffering-latency/

 

 

 

 

留下一个评论