HTTP/3要點
SPDY (HTTP/2)已經得到了主流web瀏覽器(Chrome、Firefox、Edge、Safari)和主流web伺服器(Apache、Nginx、IIS、CloudFlare)的支援。許多最流行的網站都支援它(即使是非google站點),儘管您不太可能在網上看到它(使用Wireshark或tcpdump進行嗅探),因為它總是使用SSL加密的。雖然標準允許HTTP/2在TCP上執行raw,但是所有實現都是SSL上使用它。
這裡有一個關於標準很好的一課。在網際網路之外,標準通常是法律上的,由政府管理,由所有主要利益相關者在一個房間裡討論,然後使用規則迫使人們採用它。在網際網路上,人們首先實現東西,然後如果其他人喜歡它,他們也會開始使用它。標準通常是事實上的,rfc是為已經在網際網路上執行良好的內容,記錄人們已經在使用的內容。瀏覽器/伺服器採用SPDY並不是因為它是標準化的,而是因為主要的參與者只是簡單地開始新增它。同樣的情況也發生在QUIC上:它被標準化為HTTP/3的事實是它已經被使用,而不是人們可以開始使用它的標準化里程碑。
QUIC實際上更像是TCP (TCP/2???)的新版本,而不是HTTP (HTTP/3)的新版本。它並沒有真正改變HTTP/2的功能,而是改變了傳輸的工作方式。因此,我下面的評論集中在傳輸問題上,而不是HTTP問題。
主要的標題特性是更快的連線設定和延遲。TCP要求在建立連線之前來回傳送大量資料包。SSL同樣需要在建立加密之前來回傳送大量資料包。如果網路延時很大,比如人們使用半秒ping時間的衛星網際網路,建立連線需要相當長的時間。通過減少往返,連線可以更快地建立,這樣當您單擊連結時,連結的資源就會立即彈出
下一個主要特性是頻寬。網路連線的源和目的之間總是存在頻寬限制,這幾乎總是由於擁塞。雙方都需要使用這個速度,以便他們能夠以適當的速度傳送資料包。如果傳送資料包太快,那麼它們就會被丟棄,這會在不提高傳輸速率的情況下給其他資料包造成更大的擁塞。傳送資料包太慢意味著不能最優地使用網路。
HTTP 傳統上這一點做得很糟糕。 使用單個 TCP 連線不適用於 HTTP,因為與網站的互動需要同時傳輸多個內容,因此瀏覽器打開了與 Web 伺服器的多個連線(ofollow,noindex" target="_blank">通常為 6 個 )。但是,這會打破對頻寬的估計,因為每個 TCP 連線都嘗試獨立完成,就像其他連線不存在一樣。SPDY 通過其多路複用 功能解決了這個問題,該功能將瀏覽器/伺服器之間的多個互動與單個頻寬計算相結合。
QUIC 擴充套件了這種多路複用,使得處理瀏覽器/伺服器之間的多個互動變得更加容易,而沒有任何一個互動阻止另一個互動,且具有共同頻寬。 從使用者的角度來看,這將使互動更加順暢,同時減少路由器遇到的擁塞。
我們現在來談談使用者模式棧 。 特別是在伺服器上,TCP連線由作業系統核心處理,而服務本身在使用者模式 中執行。跨核心/使用者模式邊界移動會導致效能降低。追蹤大量TCP連線會導致擴充套件性問題。有些人嘗試將服務放入核心來避免轉換,這並不可取,因為它破壞了作業系統的穩定性。我的解決方案是用BlackICE IPS和masscan,使用自定義TCP棧,利用硬體的使用者模式驅動程式,將資料包從網路晶片直接傳送到使用者模式程序,繞過核心(參見PoC || GTFO#15)。近年來,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就不太可能成為標準。
QUIC 的另一個優美的解決方案是對移動的支援。當你帶著你的膝上型電腦四處移動到不同的 WIFI 網路時,或者帶著你的手機四處移動時,你裝置的 IP 地址會發生變化的。作業系統以及協議不會優雅的關閉掉老的連線而開啟新的連線。然而,QUIC,網路連線的識別符號並不是傳統概念上的一個“socket”(源/目標 埠/地址 協議的繫結),而是一個64位的賦值到連線上的識別符號。
這意味著當你移動時,即使 IP 地址改變了,你依然能夠和 YouTube 繼續保持一個持續不間斷的視訊流,或者繼續撥打一個視訊電話而不被異常中斷。網路工程師們已經和“移動IP”的技術問題攻關了幾十年,試圖想出一個有效的解決方案。他們專注於端到端原則,也就是在你移動時以某種方式保持一個恆定的 IP 地址,這不是一個實際的解決方案。很高興看到 QUIC / HTTP/3 最終解決了這個問題。
如何使用這種新的交通工具?幾十年來,網路程式設計的標準一直是被稱為“sockets”的傳輸層API。呼叫recv()之類的函式來接收程式碼中的包。使用QUIC/HTTP/3,我們不再擁有作業系統傳輸層API。相反,它是一個更高層次的特性,可以在go程式語言中使用,或者在OpenResty nginx web伺服器中使用Lua。
我之所以提到這一點,是因為在您對OSI模型的學習中,有一件事遺漏了,那就是它最初設想每個人都編寫應用層(7)api,而不是傳輸層(4)api。應該有一些應用程式服務元素,它們可以以標準的方式為不同的應用程式處理檔案傳輸和訊息傳遞之類的事情。我認為人們正越來越多地轉向這種模式,尤其是由帶有go、QUIC、protobufs等的谷歌驅動。
我之所以提到這一點,是因為谷歌和微軟之間的差異。微軟擁有一個流行的作業系統,所以它的創新是由它在該作業系統中所能做的事情驅動的。谷歌的創新是由它可以放在作業系統上的東西驅動的。然後是Facebook和亞馬遜自己,它們必須在谷歌提供的堆疊之上(或之外)進行創新。世界上排名前五的公司依次是蘋果、谷歌、微軟、亞馬遜和facebook,因此,每一家公司推動創新的地方都很重要。
結論
在 20 世紀 70 年代,TCP 被創造出來的時候,是非常了不起的。它處理的事情,如擁塞,比其他競爭性協議要好很多。人們沒有辦法預料到會有 40 億個 IPV4 地址的出現,那時候預計現代網際網路的競爭性設計會比七八十年代要好。
IPv4 到 IPv6 的升級,很大程度上保持了 IP 的優勢。 從 TCP 到 QUIC 的升級同樣是基於 TCP 的優點的,並將其擴充套件到現代需求上。實際上令人驚訝的是,TCP 已經持續瞭如此長的時間,它在沒有升級的情況下,做得很好。