從http到QUIC

零、爲何要分享這個主題?

  • chorme瀏覽器已經支持quic協議(雖然爲了安全默認關閉,仍是草案中),但quic有望大大下降首次首屏的加載時間,解決困擾咱們好久首次渲染的性能問題。
  • http3草案: quicwg.org/base-drafts…

1、http的發展史

首先先來回顧下http的發展歷程,瞭解下http是如何來的。html

  • http是在1965年,由Ted Nelson提出的,並在Xanadu項目中實現超文本系統的原型
  • 在1989年,Tim Berners-lee提出了'超文本'(以一種無約束的方式聯繫起來的人類可讀信息)和‘超媒體’(不限於文本),搭建「"通用系統"。
  • 在1991年,就提出http/0.9,可是比較簡單,並且只有get方法,沒有首部,只能獲取html,沒有圖片和文本
  • 在1996年,提出了http/1.0,這時候就包括首部、響應碼、重定向、錯誤、條件請求、內容編碼(壓縮)等等。可是不包括共用請求,強制的host首部,緩存的選擇
  • 在1999年,提出的http/1.1,這時候就強制host首部,有虛擬主機託管,不用每一個請求發起tcp鏈接。同時也擴展了緩存相關首部、options方法、upgrate首部、Range請求、壓縮和傳輸編碼、管道化
  • 在2009年,Google工程師Mike Belshe和Roberto Peon提出了SPDY,在http以前作了一層會話。
  • 在2015年,提出了http/2.0,融合SPDY的優點,使用了二進制分幀層,多路複用,頭部壓縮,服務器推送等等。。。
  • 如下就是我整理的http發展的時間線

2、http2的特性和詳解

  • 一、名詞認識:
    • SPDY(讀做「SPeeDY」)是Google開發的基於TCP的會話層協議,用以最小化網絡延遲,提高網絡速度,優化用戶的網絡使用體驗。就是在應用層中增長1個SPDY協議,以下圖所示,在本來的應用層中,增長了SPDY層。
    • 數據幀:http/2大體分爲分幀層和數據層。數據幀第一個是length,以後是幀的類型,flags就帶有幀的標識。
    • 流:
  • 二、特性:
    • (1)、二進制傳輸,原來HTTP/1.x 是以純文本形式的報文,到了HTTP/2就 採用二進制格式傳輸數據。以下看兩種的區別。
      • 純文本解析:以純文本去顯示和解析,要不斷的去判斷增長邏輯,效率很是低。如如下僞代碼解析。
      • 二進制解析:解析起來就比純文本更加方便。如如下僞代碼的解析。代碼量少,更加方便
      • http/2把原來的"Header+Body"的消息"打散"爲數個小片的二進制"幀"(Frame),用"HEADERS"幀存放頭數據、"DATA"幀存放實體數據。HTTP/2數據分幀後"Header+Body"的報文結構就徹底消失了,協議看到的只是一個個的"碎片"。多個幀之間能夠亂序發送,根據幀首部的流標識能夠從新組裝。
    • (2)、多路複用
      • http1.1的時候,爲了解決這個方法,是將同一頁面的資源分散到不一樣域名下,提高鏈接上限,Chrome有個機制,對於同一個域名,默認容許同時創建 6 個 TCP持久鏈接,使用持久鏈接時,雖然能公用一個TCP管道,可是在一個管道中同一時刻只能處理一個請求,在當前的請求沒有結束以前,其餘的請求只能處於阻塞狀態。另外若是在同一個域名下同時有10個請求發生,那麼其中4個請求會進入排隊等待狀態,直至進行中的請求完成。
      • 多路複用很好的解決了瀏覽器限制同一個域名下的請求數量的問題,同時也更容易實現全速傳輸,畢竟新開一個 TCP 鏈接都須要慢慢提高傳輸速度。
      • 效果以下:
      • 傳輸的原理:http/2中同域名下全部通訊都在單個鏈接上完成。單個鏈接能夠承載任意數量的雙向數據流。數據流以消息的形式發送,而消息又由一個或多個幀組成,多個幀之間能夠亂序發送,由於根據幀首部的流標識能夠從新組裝。
    • (3)、頭部壓縮
      • 經過Hapck算法,在客戶端和服務器兩端創建「字典」,經過索引去除重複請求,查找壓縮方案。
      • 使用霍夫曼編碼,能接近gzip的壓縮率,也能壓縮字符串
      • 例以下圖中的兩個請求,請求一發送了全部的頭部字段,第二個請求則只須要發送差別數據,這樣能夠減小冗餘數據,下降開銷
    • (4)、服務器推送(Server push)
      • 在 HTTP/2.0 中,服務器能夠向客戶發送請求以外的內容,好比正在請求一個頁面時,服務器會把頁面相關的 logo,CSS等文件直接推送到客戶端,而不會等到請求來的時候再發送,由於服務器認爲客戶端會用到這些東西。這至關於在一個 HTML 文檔內集合了全部的資源。以下圖所示:
      • 服務端能夠主動推送,客戶端也有權利選擇是否接收。若是服務端推送的資源已經被瀏覽器緩存過,瀏覽器能夠經過發送RST_STREAM幀來拒收。主動推送也遵照同源策略,換句話說,服務器不能隨便將第三方資源推送給客戶端,而必須是通過雙方確認才行。
    • (5)、加密傳輸
      • 由於主流的瀏覽器Chrome、Firefox等都公開宣佈只支持加密的HTTP/2,因此「事實上」的HTTP/2是加密的。也就是說,互聯網上一般所能見到的HTTP/2都是使用"https」協議名,跑在TLS上面。HTTP/2協議定義了兩個字符串標識
    • (6)、優先級
      等等
  • 三、http2時代和http1不一樣的優化方法:
    • (1)、http1使用Spriting合併多張小圖爲一張大圖,再用JavaScript或者CSS將小圖從新「切割」出來的技術。在http2由於多路複用的應用就不須要這麼作了。
    • (2)、http1.1時代使用內聯(Inlining)去防止發送不少小圖請求的技巧,將圖片的原始數據嵌入在CSS文件裏面的URL裏,減小網絡請求次數。
    • (3)、在http1.1時代要拼接(Concatenation)將多個體積較小的JavaScript使用webpack等工具打包成1個體積更大的JavaScript文件,但若是其中1個文件的改動就會致使大量數據被從新下載多個文件。,在http/2時代也不須要這麼作,能夠分不少js文件去加載。
    • (4)、http1.1時代使用多域名去實現假並行提升傳輸效率,在http2時代就不須要使用多域名,一個域名創建tcp鏈接後就能夠多路複用去傳輸。

3、http2存在的問題

  • 一、HTTP/2都是基於TCP去實現的,可是當數據發生丟包的時候會發生阻塞(即tcp hol Blocking)進行數據重傳,繼而觸發「擁塞發生」,其擁塞窗口降爲1,在未收到ack以前其餘包阻塞。以下圖所示:
  • 二、在弱網狀況下,頻繁丟包,http2的多路複用反而比http1更低效。由於TCP爲了保證可靠傳輸,有個特別的「丟包重傳」機制,丟失的包必需要等待從新傳輸確認,HTTP/2出現丟包時,整個 TCP 都要開始等待重傳,那麼就會阻塞該TCP鏈接中的全部請求。而對於 HTTP/1.1 來講,能夠開啓多個 TCP 鏈接,出現這種狀況反倒只會影響其中一個鏈接,剩餘的 TCP 鏈接還能夠正常傳輸數據。
    • http2弱網絡測試
  • 三、tcp鏈接時先要進行3次握手來確認鏈接成功,也就是須要至少消耗1.5個RTT才能進行數據傳輸。
  • 四、使用https時,還須要TLS協議進行安全傳輸,使用TLS也須要一個握手過程。TLS有2個版本,TLS1.2和TLS1.3,每一個版本創建鏈接所花的時間也不一樣,大體須要1~2個RTT。SSL進行中,要進行公鑰和私鑰傳輸,以下圖:

4、QUIC的介紹和使用

Google設計了一種新的協議QUIC,讓HTTP跑在UDP上而不是TCP上。webpack

  • (1)定義:QUIC(Quick UDP Internet connections)快速udp網絡鏈接,由谷歌發明的。顧名思義,是基於UDP作傳輸層,而與以前的tcp作傳輸層有區別。
  • (2)原理:使用UDP實現一個可靠的多路複用傳輸層。UDP是面向數據報文的,數據包之間沒有阻塞約束,QUIC就是利用這個特性解決傳輸層的對頭阻塞問題。
  • (3)功能
    • 【1】引入了相似HTTP/2的「流」和「多路複用」,單個「流"是有序的,可能會由於丟包而阻塞,但其餘「流」不會受到影響,完全解決TCP中隊頭阻塞的問題。 nginx

    • 【2】實現了相似TCP的流量控制、傳輸可靠性的功能,QUIC在UDP的基礎之上增長了一層來保證數據可靠性傳輸。它提供了數據包重傳、擁塞控制以及其餘一些TCP中存在的特性。如下是TCP、UDP和QUIC的區分: web

    • 【3】實現了快速握手功能: 0 Rtt算法

      • 使用UDP規避了三次握手
      • 使用DH加密來規避TLS交互
      • 首包就能夠發送數據
      • 並且有1次Server Config的緩存,後面只要緩存不失效,重連也無需TLS交互。
    • 【4】可靠性:chrome

      • 方法:
        • (1)、單調遞增seq
        • (2)、單向冗餘糾錯(異或)
        • (3)、失敗重傳進行處理
      • 當發生丟包時
        • (1)、嘗試使用前向糾錯來修復
        • (2)、不能fec,則失敗重傳。

      舉個例子:當發送數據A和B,增長髮送1個數據C等於A和B的異或,接收方接到這3個包的任意2個包,異或1下就能夠獲得第3個包瀏覽器

    • 【5】、quic擁塞窗口:緩存

      • 實現了tcp的Cubic和NewReno算法
      • 默認採用Cubic
      • nack機制,由接收端告知哪幾個包丟失
      • Tail Loss Probes更及時的重傳
    • 【6】、其餘安全

      • 鏈接性:使用connection id來識別從新鏈接的請求
      • 流量控制:能夠針對鏈接控制,也能夠對具體的stream id進行控制
  • (3)優點:
    • 【1】、效率高,傳輸快
    • 【2】、谷歌調優後的QUIC更是重建了可靠性和有序性,但減小了鏈接次數,尤爲是對於加密鏈接來講,可以使用先前協商過的相同加密恢復舊鏈接,而不須要任何額外的往返。
    • 【3】、QUIC 能夠實現可靠傳輸,並且相比於 TCP,它的流控功能在用戶空間而不在內核空間,那麼使用者就 不受限於 CUBIC 或是 BBR,而是能夠自由選擇,甚至根據應用場景自由調整優化。
  • (4)quic支持情況:
    • 運營商:udp降級,在國內部分地區的運營商都會針對 UDP 協議QOS限速或者丟包,這就致使 UDP 效率低下,或許速度會比正常使用TCP協議還慢不少。
    • chrome支持:經過chrome://flags/#enable-quic控制,顯示quic的協議,看到Experimental QUIC protocol改爲enabled,重啓瀏覽器就能夠看到,不過要這個網站支持quic才行。
    • nginx暫不支持

5、迎接http3的來臨

QUIC 基於 UDP 實現,是 HTTP/3 中的底層支撐協議,該協議基於 UDP,又取了 TCP 中的精華,實現了即快又可靠的協議。也許http3普及以後,如今不少作的性能優化操做就不須要了。 性能優化

相關文章
相關標籤/搜索