啓用HTTP/2

HTTP歷史

HTTP/0.9是個相當簡單的協議,它只有一個GET方法,沒有首部。HTTP/1 新增了大量內容:首部,晌應碼,重定向,錯誤,條件請求,內容編碼,更多的請求方怯。HTTP/1.1強制增加host首部,增加緩存相關首部,傳輸編碼,默認持久連接等。HTTP2基於google的SPDY,基本就是SPDY規範化,2015年HTIP/2 成爲正式協議。0.9-2的協議都是基於tcp協議。爲什麼http3會有基於udp實現的討論?即使基於udp也仍然要在應用程序重複實現tcp已經實現的可靠連接,擁塞控制等特性。基於udp實現的考慮是傳輸層協議內置在操作系統裏實現,應用層開發人員沒有對它的控制權,如果能將tcp這些特性移到應用層,就可以快速發展迭代。

HTTP/1.1問題

1.隊頭阻塞

HTTP協議是建立在TCP協議之上請求應答模式的半雙工通信協議,而瀏覽器很少只從一個域名獲取一份資源,大多數時候,它希望能同時獲取許多資源。假設客戶端與服務器開啓一條TCP連接通信,客戶端需要獲取10個資源,只能是一個個的獲取。客戶端首先請求第1個資源,接收到服務端響應後再繼續請求第2個,依此類推,如果獲取第一個資源比較慢就會阻塞後面的請求。客戶端要想發起多個並行請求以提升性能,則必須使用多個 TCP 連接,但是每個連接仍會受到“隊頭阻塞”的影響。現代瀏覽器會針對單個域名開啓6個TCP連接。一個客戶端對任何服務器或代理最多隻能維護2條持久連接,以防服務器過載。

2.低效的TCP利用

如果沒有開啓keepalive則每個請求都會重複TCP連接建立的過程,即三次握手和四次握手。開啓keepalive後主要是TCP擁塞控制的影響。

3.臃腫的首部

1.1版本無法壓縮首部,首部通常有很多,並且如果帶有cookie則會更大。

4.無法指定優先級

5.第三方資源

Web頁面上請求的很多資源完全獨立於站點服務器的控制,我們稱這些爲第三方資源。很多第三方資源都不在 Web 開發者的控制範圍內,所以很可能其中有些資源的性能很差,會延遲甚至阻塞頁面誼染。

HTTP/2特性

二進制協議

HTTP/1.1是文本協議,而HTTP/2是二進制協議。經過網絡傳輸必然是都二進制,這裏所謂文本協議,二進制協議的意思應當是報文的內容。HTTP/1.1中request line和header都是ASCII編碼,而body內容類型依據content-type判斷,並且判定body是否結束是根據content-length或者分塊傳輸,要解析整個HTTP報文內容,都是根據文本字符CRLF來解析。所以HTTP/1.1的報文是經過文本編碼的二進制再交付給TCP傳輸。HTTP/2中保留了HTTP/1.1 的語義(包括各種動詞、方法、首部),不同的是傳輸期間對它們的編碼方式變了。HTTP/2 將所有傳輸的信息分割爲更小的消息和幀,並採用二進制格式對它們編碼。

+-----------------------------------------------+
    |                 Length (24)                   |
    +---------------+---------------+---------------+
    |   Type (8)    |   Flags (8)   |
    +-+-------------+---------------+-------------------------------+
    |R|                 Stream Identifier (31)                      |
    +=+=============================================================+
    |                   Frame Payload (0...)                      ...
    +---------------------------------------------------------------+

其中length佔用24bit,表示payload數據的長度,24bit能表示的數值爲0到$2^{24}$-1,而1mb=$2^{20}$,所以理論上payload最大是$2^4$mb,$2^{14}$是默認的最大幀大小。這樣服務器只需要讀取到length與type,也就是前9個字節,就只可以知道數據的長度,以及數據幀的類型。

可以理解爲http協議的各種請求方法,首部語義都保留了,區別在於,HTTP/1.1是把這些明文內容使用CRLF分隔直接傳輸,而HTTP/2則對明文內容封裝到幀的payload裏面。

請求與響應複用

HTTP/2 的主要目標是通過支持完整的請求與響應複用來減少延遲,HTTP/2只會建立並複用一條TCP連接。客戶端和服務器可以將 HTTP 消息分解爲互不依賴的幀,然後交錯發送,最後再在另一端把它們重新組裝起來(根據Stream Identifier區分)。客戶端可以並行交錯地發送多個請求,請求之間互不影響。服務器端可以並行交錯地發送多個響應,響應之間互不干擾。

連接管理

大多數 HTTP 傳輸都是短暫的,而 TCP 則針對長時間的批量數據傳輸進行了優化。 通過重用相同的連接,HTTP/2 既可以更有效地利用每個 TCP 連接,也可以顯著降低整體協議開銷。

HTTP/1.1的持久連接是有超時時間的,HTTP/2沒有超時時間的概念,它可以被認爲是永久連接的,但是不可能是一直連着的,即使HTTP沒有明確規定超時,TCP也有超時的。所以如何理解這個永久呢?

HTTP/2 connections are persistent. For best performance, it is expected that clients will not close connections until it is determined that no further communication with a server is necessary (for example, when a user navigates away from a particular web page) or until the server closes the connection.

Servers are encouraged to maintain open connections for as long as possible but are permitted to terminate idle connections if necessary.

HTTP/2連接是持久的,爲了最好的性能,客戶端不應當關閉連接,直到它認爲不需要與服務器進行進一步的通信(例如,當用戶從一個特定的網頁導航離開時)或者直到服務器關閉連接。服務端也應當儘可能長的保持連接,但是也允許服務器主動關閉連接釋放資源。

數據流優先級

HTTP/2 標準允許每個數據流都有一個關聯的權重和依賴關係。

首部壓縮

HTTP/2 使用 HPACK 壓縮格式壓縮請求和響應標頭元數據。

流控制

流控制是一種阻止發送方向接收方發送大量數據的機制,以免超出後者的需求或處理能力: 發送方可能非常繁忙、處於較高的負載之下,也可能僅僅希望爲特定數據流分配固定量的資源。 例如,客戶端可能請求了一個具有較高優先級的大型視頻流,但是用戶已經暫停視頻,客戶端現在希望暫停或限制從服務器的傳輸,以免提取和緩衝不必要的數據。 再比如,一個代理服務器可能具有較快的下游連接和較慢的上游連接,並且也希望調節下游連接傳輸數據的速度以匹配上游連接的速度來控制其資源利用率;等等。

服務器推送

服務器可以對一個客戶端請求發送多個響應,除了對最初請求的響應外,服務器還可以向客戶端推送額外資源。這裏的推送並不意味着可以全雙工通信了,可以替換websocket,前提是客戶端主動發起一次請求才可以。另外,在使用 nginx 作爲反向代理時根本不支持這種推送。

啓用HTTP/2

HTTP/2 over https,因此要啓用HTTP/2,必須現在服務器配好證書。要啓用HTTP/2無非就是需要客戶端與服務器都支持HTTP/2通信協議,幾乎每個現代的瀏覽器和版本高一點的web服務器都支持 HTTP/2。只需要服務器開啓HTTP/2,客戶端會優先使用HTTP/2連接,如果服務器不支持HTTP/2,則會退回到HTTP/1.1 。

現代服務端部署方式通常不只有一個web服務器,從瀏覽器發出的請求到最終接口獲取數據,中間可能存在諸多代理,比如雲服務的slb,gateway,k8s ingress,後端服務tomcat等,問題在於是否需要全鏈路啓用HTTP/2?如果後端服務器tomcat啓用HTTP/2,但是中間nginx沒有啓用,本質上還是相當於沒有啓用。這個問題可以類比https,通常我們只會在整個鏈路的最邊緣節點配置一次https,由於最邊緣節點到後端服務幾乎是內網訪問,不存在中間人攻擊問題,所以從最邊緣節點到後端服務完全沒有必要再次加密解密。

HTTP/2 的主要優點是可以提升高延遲、低帶寬連接的速度,連接到邊緣服務器(在這種情況下爲反向代理)的用戶通常處在這樣的網絡環境下。從反向代理到其他 Web 基礎架構的流量一般處於低延遲、高帶寬、短距離的網絡環境中(即使不是同一臺機器,也通常是相同的數據中心),因此此場景下通常不需要考慮 HTTP/1.1 的性能問題。

反向代理到服務器的連接數不受限於瀏覽器設置的 6 個連接。Nginx 已經聲明,它不會爲代理連接實現HTTP/2。

綜上,如果要啓用HTTP/2,只在最邊緣節點啓用就可以了。

參考文檔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章