關於HTTP/3背後你所不知道的

banq發表於2018-11-20

HTTP / 3將標準化,作為一個老協議人,我想我會寫一些評論。
谷歌擁有最受歡迎的網路瀏覽器(Chrome)和兩個最受歡迎的網站(#1 Google.com#2 Youtube.com)。因此,他們可以控制未來的Web協議開發。他們的第一次升級稱為SPDY(發音為“speedy”),最終標準化為HTTP的第二個版本,即HTTP/2。他們的第二次升級稱為QUIC(發音為“quick”),標準化為HTTP/3。
主要網路瀏覽器(Chrome,Firefox,Edge,Safari)和主要網路伺服器(Apache,Nginx,IIS,CloudFlare)已經支援SPDY(HTTP/2)。許多最受歡迎的網站都支援它(即使是非谷歌網站),儘管你不太可能線上上看到它(用Wireshark或tcpdump嗅探),因為它總是用SSL加密。雖然標準允許HTTP/2透過TCP執行原始,但所有實現僅透過SSL使用它。
這裡有一個關於標準的好教訓。在網際網路之外,標準通常是法律上的由政府管理,驅動所有主要利益相關者進入一個房間並將其擬定出來,然後使用規則迫使人們採用它。在網際網路上,人們首先建立實現一個新事物,然後如果其他人喜歡它,他們也會開始使用它,因此,標準通常是事實上的。
RFC是針對已經在網際網路上執行良好的內容編寫的,記錄了人們已經在使用的內容。瀏覽器/伺服器採用SPDY不是因為它是標準化的,而是因為主要參與者開始使用它。QUIC正在發生同樣的事情:它被標準化為HTTP/3的事實反映了它已被使用,而不是處於通往標準化實施里程碑階段。

QUIC實際上是新版本的TCP(TCP / 2 ???)而不是新版本的HTTP(HTTP / 3)。它並沒有真正改變HTTP / 2的作用,而是改變了傳輸的工作方式。因此,我在下面的評論側重於傳輸問題而不是HTTP問題。

HTTP3主要特點是更快的連線設定和延遲
TCP需要在建立連線之前來回傳送多個資料包。SSL再次需要在建立加密之前來回傳送許多資料包。如果有很多網路延遲,例如當人們使用具有半秒ping時間的衛星網際網路時,建立連線可能需要相當長的時間。透過減少往返次數,連線可以更快地進行設定,因此當您單擊連結時,連結的資源會立即彈出

頻寬
網路連線的源和目標之間始終存在頻寬限制,這幾乎總是由於擁塞。雙方都需要發現一種速度級別,以這個速度他們能夠以合適的速率傳送資料包。傳送資料包太快也不行,會被丟棄,導致其他人擁塞更多,這樣並不會提高傳輸速率。傳送資料包太慢也不行,意味著網路使用不當。

HTTP傳統上這一點實現得很糟糕,使用單個TCP連線不適用於HTTP,因為與網站的互動需要同時傳輸多個內容,因此瀏覽器會開啟多個連線(通常為6個)。但是,這會打破頻寬估計,因為每個TCP連線都嘗試獨立完成,就像其他連線不存在一樣。SPDY透過其多路複用  功能解決了這個問題,該功能將瀏覽器/伺服器之間的多個互動放入一個連線。

QUIC擴充套件了這種多路複用,使得處理瀏覽器/伺服器之間的多個互動變得更加容易,而沒有任何一個互動阻止另一個互動,但都具有同樣的頻寬。從使用者的角度來看,這將使互動更加順暢,同時減少路由器遇到的擁塞。
 

使用者模式堆疊
TCP的問題,特別是在伺服器上,是TCP連線由作業系統核心處理,而服務本身在usermode中執行。跨核心/使用者模式邊界移動會導致效能問題。跟蹤大量TCP連線會導致可伸縮性問題。有些人嘗試將服務放入核心,以避免轉換,這是一個糟糕的,因為它破壞了作業系統的穩定性。我自己的解決方案,使用BlackICE IPS和masscan,就是使用 硬體的使用者模式驅動程式,將資料包從網路晶片直接傳送到使用者模式程式,繞過核心(參見PoC || GTFO#15),使用我自己的自定義TCP堆疊。近年來,這已成為DPDK的流行 套件。

但是,從TCP遷移到UDP可以在沒有使用者模式驅動程式的情況下獲得相同的效能。 您可以呼叫recvmmsg()  一次接收一堆UDP資料包,而不是呼叫眾所周知的recv()函式來一次接收一個資料包。它仍然是核心/使用者模式轉換,但是一次性收到的一百個資料包的開銷,而不是每個資料包的轉換。

在我自己的測試中,使用典型的recv()  函式限制為大約500,000 UDP /秒,但使用recvmmsg()和其他一些最佳化(使用RSS的多核),你可以在低端四核伺服器上獲得5,000,000 UDP /秒。由於每個核心的擴充套件性很好,因此遷移到具有64個核心的強大伺服器應該可以進一步改進。

BTW,“RSS”是網路硬體的一項功能,它將傳入的資料包分成多個接收佇列。
多核可擴充套件性的最大問題是兩個CPU核心需要同時讀取/修改同一個東西,因此共享相同的UDP佇列成為最大的瓶頸。
因此,首先英特爾和其他乙太網供應商新增了RSS,為每個核心提供了自己的非共享資料包佇列。Linux和其他作業系統升級UDP以支援單個套接字(SO_REUSEPORT)的多個檔案描述符來處理多個佇列。
現在,QUIC使用這些發展成果,允許每個核心管理自己的UDP資料包流,而沒有與其他CPU核心共享內容的可擴充套件性問題。我之所以提到這一點,是因為我親自與英特爾硬體工程師討論過在2000年有多個資料包佇列問題。這是一個常見的問題,也是一個明顯的解決方案,在過去的二十年中,它看起來很有趣,直到它出現在高階的HTTP / 3。
如果沒有網路硬體中的RSS,QUIC就不太可能成為標準。


移動支援
當您將膝上型電腦移動到不同的WiFI網路或隨手機移動時,您的IP地址可能會發生變化。作業系統和協議不能正常關閉舊連線並開啟新連線。但是,對於QUIC,連線的識別符號不是“套接字”(源/目標埠/地址協議組合)的傳統概念,而是分配給連線的64位識別符號。
這意味著,當您四處移動時,即使IP地址發生變化,您也可以繼續從YouTube不間斷地繼續流式傳輸,或者繼續進行影片電話呼叫,而不會被丟棄。幾十年來,網際網路工程師一直在努力解決“移動IP”問題,試圖提出一個可行的解決方案。他們專注於端到端原則,以便在您移動時以某種方式保持一個恆定的IP地址,這不是一個實際的解決方案。很高興看到QUIC / HTTP / 3最終透過現實世界中的工作解決方案來解決這個問題。

如何使用這種新的運輸?幾十年來,網路程式設計的標準一直是傳輸層API,  稱為“套接字”。你呼叫recv()之類的函式的地方 在您的程式碼中接收資料包。使用QUIC / HTTP / 3,我們不再擁有作業系統傳輸層API。相反,它是一個更高層的功能,您可以在go  程式語言中使用,或者在OpenResty nginx Web伺服器中使用Lua。

我之所以提到這一點,是因為您對OSI模型的教育中缺少的一點是,它最初設想每個人都在編寫應用層(7)API而不是傳輸層(4)API。應該有像應用程式服務元素之類的 東西,它們可以以標準方式處理檔案傳輸和訊息傳遞等不同應用程式。我認為人們越來越多地轉向這種模式,特別是谷歌用goQUIC驅動,protobufs等。

我之所以提到這一點,是因為谷歌和微軟之間的對比。微軟擁有一個流行的作業系統,因此它的創新是由它在該作業系統中的功能所驅動的。谷歌的創新是由它可以放在作業系統之上的。然後有Facebook和亞馬遜自己必須在谷歌提供它們的堆疊之上(或之外)進行創新。按順序排名世界排名前五的公司是Apple-Google-Microsoft-Amazon-Facebook,因此每個公司推動創新都很重要。

結論
當TCP在20世紀70年代建立時,它是崇高的。它處理的事情,如擁塞,比競爭協議要好得多。從IPv4到IPv6的升級在很大程度上保持了IP的優勢;從TCP到QUIC的升級同樣基於TCP的優點,但將其擴充套件到現代需求。實際上,令人驚訝的是,TCP已經持續了這麼長時間沒有升級。

 

相關文章