HTTP 3協議詳解

安全劍客發表於2019-10-26
HTTP/3又迎來一個里程碑:近日Cloudflare官方宣其邊緣網路上已全面提供QUIC和HTTP/3支援。那麼HTTP/3可以帶來哪些變化和優勢呢? 對Internet的使用者,並且通過瀏覽器和其他客戶端與站點進行高效互動。可通過使用最新Chrome Canary瀏覽器以HTTP/3 UDB協議和伺服器互動,對於使用 命令行客戶端的人,最新版本的curl也提供了對HTTP/3的支援。本文蟲蟲將介紹HTTP/3的發展歷程,以及使用者如何啟用HTTP 3,如何通過瀏覽器Chrome及 命令行客戶端curl使用HTTP 3。

首先,我們先來介紹下HTTP多年來的發展,以便更好地理解HTTP/3。

HTTP/1.0

HTTP協議源於1996年,在這一年釋出了HTTP/1.0規範(0.x版本忽略),該規範定義了我們今天常見的基本HTTP文字規格定義。在HTTP/1.0中定義了客戶端和伺服器之間的每個請求/響應交換都要建立一個新的TCP連線,所以在進行每個請求均需大家熟知的"三次握手,四次揮手"的歷程,因此請求難免會產生延遲。比如一個典型的HTTP/TLS過程,圖解如下:

HTTP 3協議詳解HTTP 3協議詳解

而且,為了避免將無法處理的資料包泛洪到網路中,TCP協議對建立的連線使用使用了一種稱為"慢啟動"的預熱暫緩期用來給TCP堵塞控制演算法確定可以傳輸的資料量,而不是在建立連線後儘快傳送所有未完成的資料。由於每一個新連線都必須經過這個緩慢的啟動過程,這也成了網路效能的一個瓶頸。

HTTP/1.1 keep-alive

隨之而來的的HTTP/1.1版本中引入"keep-alive(保活)"連線的方法來解決這些問題。通過保活技術,可以讓客戶端重用TCP連線,而不需要每次都重新建立TCP連線,從而解決初始連線建立和緩慢連線的問題。但這並不能從實質上解決問題,儘管多個請求可以共享同一個連線,但是仍然必須一個接一個地序列化它們,因此客戶端和伺服器只能在任何給定時間為每個連線執行一次請求/響應交換。

隨著網路和Web技術的發展,每個網站所需的資源(CSS,JS 指令碼,圖片,視訊等)的增加,瀏覽器在獲取和渲染呈現網頁時對併發性的需要越來越迫切。但是,由於HTTP/1.1只允許客戶端每次只能進行一個HTTP請求/響應交換,因此在網路層上獲得併發性的唯一方法是並行使用多個TCP連線,這樣一來就無法享受保活技術帶來的好處。

HTTP/2 SPDY

又過了十多年後,出現了SPDY,然後是HTTP/2規範。它首先引入了HTTP流的概念。通抽象HTTP實現將不同的HTTP交換併發地複用到同一個TCP連線上,瀏覽器可以更有效地重用TCP連線。
HTTP 3協議詳解HTTP 3協議詳解

HTTP/2解決了單個TCP連線的使用效率低的問題,可以通過同一連線同時傳輸多個請求/響應。但是如果傳輸中發生資料丟包,即使丟失的資料僅涉及單個請求,所有請求和響應也同樣會受到資料包丟失的影響而需要重傳。因為儘管HTTP/2可以在不同的流上隔離不同的HTTP交換,但是底層的TCP並無法對他們進行區別,TCP能看到的只是沒有任何標誌的位元組流。

TCP的作用是以正確的順序從一個端點到另一端點傳遞整個位元組流。當承載某些位元組的TCP資料包在網路路徑上丟失時,它將在流中造成間隙,並且TCP需要在檢測到丟失時通過重新傳送受影響的資料包來填充它。這樣即使丟失此後沒有丟失並且屬於完全獨立的HTTP請求,也不能將資料包後的已成功傳輸的資料包傳遞給應用層。因此,最終會導致他們也會產生不必要的延遲。這個問題被稱為TCP head-of-line blocking (TCP隊頭阻塞)。

HTTP 3協議詳解HTTP 3協議詳解

為了解決隊頭阻塞問題,HTTP/2中也引入了多路複用(Multiplexing)技術,將TCP流可以傳輸的資料分為若干訊息,每個訊息再劃分為最小的二進位制幀組成,這樣即使一個請求被阻塞了,也不會影響其他請求,如上圖中第四種情況所示。

HTTP/3 QUIC

當然這些改良TCP的方案都只能部分解決問題,為了徹底從根解決問題。那就需要徹底更換底層的TCP協議,這就是谷歌多年探索的基於UDP的QUIC協議,這也是HTTP/3的基礎。QUIC協議中在傳輸層將資料流作為基本,QUIC流共享相同的QUIC連線,需要額外的握手和慢啟動來建立新的QUIC流,通過底層使用UDP協議以及將QUIC資料包封裝在UDP資料包的頂部,實現QUIC流的獨立交付。因此在大多數情況下,影響一個流的丟包不會影響其他流。

與TCP相比,使用UDP可以提供更大的靈活性,並且可以使QUIC實現完全存在於使用者空間中。協議實現的更新不再依賴於作業系統更新。藉助QUIC,可以將HTTP級別的流簡單地對映為QUIC流的頭,從而繼承HTTP/2的所有好處,而不會產生隊頭阻塞問題。

HTTP 3協議詳解HTTP 3協議詳解

QUIC還結合了典型的3次TCP握手和TLS 1.3的握手。這樣預設情況就可以提供加密和身份驗證,並且加速連線的建立。就算HTTP會話中的初始請求需要新的QUIC連線,在資料開始流動之前所引起的等待時間也較低。

HTTP 3協議詳解HTTP 3協議詳解

HTTP/3的使用

HTTP/3和QUIC給我們帶來開天闢地的變化,可以從根本上解決HTTP標準許久以來的許多問題和缺陷。那麼我們如何立刻使用它帶來的福利呢?

quiche框架

為了支援推廣HTTP/3 Cloudflare使用Rust開發並開源一個HTTP/3和QUI的應用框架,而且還給該應用使用一個非常可餐的名字quiche(乳蛋餅)和logo,估計以藉此吸引人們儘快品嚐HTTP/3製成的美食。

quiche的原始碼託管在github上(github:/cloudflare/quiche),在clone原始碼後,可以通過cargo編譯(注意需要rust 1.38及更新的版本,BoringSSL及其windows版本NASM):

cargo build -examples

quiche也提供了以docker為基礎的實驗環境包括http3-client, http3-server, 客戶端和伺服器端,使用方法如下:

docker編譯:

docker build -t cloudflare-quiche

.

進行HTTP/3請求

docker run -it cloudflare-quiche http3-client Url
網站啟用

目前Cloudflare的選擇性開部分放客戶如已經可以通過簡單手動設定啟用HTTP/3功能,方法是在Cloudflare儀表板,手動在"網路"選項卡開啟開關:
HTTP 3協議詳解HTTP 3協議詳解

客戶端使用

目前知名瀏覽器谷歌Chrome和Firefox都已經實驗性提供對HTTP/3的支援。Chrome在Canary,Firefox將在Nightly正式正式提供支援。

Chrome瀏覽器:首先需要下載並安裝最新的Canary版本。然後,通過設定以下命令列引數啟動Chrome Canary:

"--enable-quic"和" --quic-version = h3-23"

然後就可以支援HTTP/3,可以通過Chrome開發人員工具中的"網路"標籤頁來檢查使用的協議版本:
HTTP 3協議詳解HTTP 3協議詳解
注意到協議型別為"http2+quic/99",這就是表示Http3。

使用curl

curl最新版7.66,也新增了對HTTP/3的實驗性支援。我們可以下載編譯試用,在此前蟲蟲文章中對此介紹過。

要使用HTTP/3需要使用新新增的 "--http3"標誌來進行請求:

curl -I URL --http3

HTTP 3協議詳解HTTP 3協議詳解

原文地址: https://www.linuxprobe.com/detailed-http-3-protocol.html

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31559985/viewspace-2661531/,如需轉載,請註明出處,否則將追究法律責任。

相關文章