筆者在過去分析了諸多能夠減小 HTTPS 傳輸延遲的方法,如分佈式 Session 的複用;算法
啓用 HSTS,客戶端默認開啓 HTTPS 跳轉;採用 HTTP/2 傳輸協議;使用 ChaCha20-Poly1305 算法減小移動端 CPU 運算時間等。安全
經過這些方法,能夠在很大程度上優化 HTTPS 在傳輸上的延遲,給網站用戶帶來較好的訪問體驗。服務器
最近筆者又在考慮經過動態調節 TLS Record Size 來減小 HTTPS 傳輸延遲。分佈式
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 抓包spa
Nginx 默認的 ssl_buffer_size 大小爲 16KB(不支持動態調整),這就是一個 TLS Record Size 的大小。舉例說明, 假如資源文件的大小爲 1600KB,那麼就會被拆分爲 100 個 TLS Record 傳送到客戶端。blog
在傳輸過程當中此時會出現這樣的問題:圖片
一、TLS Record Size 越大,被拆分的 TCP 包會過多,在傳輸過程當中,若是 TCP 出現丟包狀況,那麼 TLS Record 到達客戶端的時間就會變長,而客戶端必須等到收到完整的 TLS Record 纔可以進行解密;TLS Record 及 TCP 包的關係以下圖所示:
△ 圖片來源:igvita.com
二、若是 TLS Record Size 較小,則 TCP 丟包對 TLS Record 的影響就較小了,可是於此同時,TLS Record 頭部就變多了,可能還會下降鏈接的吞吐量。
綜上所述,能夠知道切割太小的 Record Size 會產生額外的消耗;而切割過大的 Record Size 會致使延遲。筆者認爲能夠根據 TCP 窗口大小來合理調整 TLS Record 大小能夠有效下降 HTTPS 傳輸時形成的延遲。
根據以上的論點,咱們能夠得出這樣的結論:在 TCP 慢啓動的過程當中,能夠將 TLS Record Size 調整小點;由於這個過程當中 TCP 連接的擁塞窗口(cwnd )較小,TCP 連接的吞吐量也較小;在 TCP 鏈接結束慢啓動以後,TLS Record 的大小能夠增大一些,隨着時間的推移,最終將 TLS Record 的大小調整到最大(也即 16KB)。
大體的算法規則爲:
一、在新鏈接以及 TCP 慢啓動階段,將 TLS Record 大小調整爲大約 1 個 TCP 包的大小;
二、在必定的階段,也即發送必定數量的 Record Size 以後,採用較大的 TLS Record Size ;
三、隨着時間的推移,採用最大的TLS Record Size 大小,也即 16KB。
經過 WireShark 抓包,對這個過程進行驗證:
階段一:在剛開始,TLS Record Size 爲 1393 Byte。
階段二:一段時間以後,TLS Record Size 爲 4253 Byte。
階段三:最後,TLS Record Size 動態變爲 16408 Byte。
上圖三個階段的抓包結果驗證了動態 TLS Record Size 的算法規則,經過對動態調節 TLS Record Size 能夠有效下降 HTTPS 傳輸時的延遲,爲客戶帶來更好的體驗。
目前,又拍雲 CDN 平臺已經徹底支持動態調整 TLS Record Size ,對網站速度有更高要求的朋友能夠經過開啓又拍雲 CDN,來使用動態 TLS Record Size,讓網站傳輸速度更快,給用戶更好的體驗。