- 原文地址:Some notes about HTTP/3
- 原文做者:Errata
- 譯文出自:掘金翻譯計劃
- 本文永久連接:github.com/xitu/gold-m…
- 譯者:Starrier
- 校對者:HarderChen、Xekin-FE
HTTP/3 即將成爲之後的標準。做爲協議的老用戶,我以爲本身應該寫點什麼。html
Google (pbuh) 擁有最受歡迎的瀏覽器(Chrome)和兩個最受歡迎的網站(#1 Google.com #2 Youtube.com)。所以,谷歌手握將來 Web 協議的開發權。他們把第一次升級的協議稱爲 SPDY(發音同 "speedy"),也就是以後被標準化的 HTTP 的第二個版本,即 HTTP/2。他們將第二次升級的協議稱爲 QUIC(發音同 "quick"),也就是即將被標準化的 HTTP/3。前端
目前主流的 Web 瀏覽器(chrome、Firefox、Edge、safari)和主流的 Web 服務器(Apache、Nginx、IIS、CloudFlare)都已經對 SPDY (HTTP/2) 進行了支持。許多受歡迎的網站也對其進行了支持(甚至是非谷歌站點),儘管你不太可能在網上看到它(用 wireshark 或者 tcpdump 進行檢測),由於它一直是用 SSL 進行加密的。儘管該標準容許 HTTP/2 在 TCP 上運行,但實際上全部的應用都是 SSL 進行的。android
這裏有一個關於標準的知識點。在互聯網範圍之外,標準一般都是依附於法律之上,由政府進行管理。全部的主要利益相關人員在一個會議室進行制定,而後用法律強迫人們承認並使用它。然而在互聯網上則有所不一樣,人們首先會實現標準,而後由用戶的承認度決定是否開始使用。標準一般都是事實,RFC 文檔是爲了在互聯網上已經正常工做的內容所編寫的,用於記錄人們已經在使用的內容。SPDY 被瀏覽器/服務器採用的緣由不只僅是由於它被標準化,還由於互聯網的主要廠商都開始添加對它的支持。QUIC 也是如此:它正在被標準化爲 HTTP/3 則反映了它正在被使用,這不只僅是一個里程碑,由於大多數人都已經開始在實踐中開始應用這一協議。ios
QUIC 實際上更像是 TCP(TCP/2)的新版本,而不是 HTTP(HTTP/3)的新版本。由於它並無真正改變 HTTP/2 所作的事情,而是改變了傳輸所作的工做方式。所以,我下面的評論重點是傳輸問題,而不是 HTTP 問題。git
主要的重點特性是更快的鏈接設置和更短的延遲。TCP 須要在鏈接創建以前來回發送多個數據包。SSL 會在加密創建之間請求來回發送多個數據包。若是有大量網絡延遲,好比人們使用半秒每次的衛星互聯網 ping 通訊,它可能須要很長的時間來創建一個鏈接。經過減小往返次數,鏈接能夠更快地創建,所以當你點擊一個連接時,連接資源就會馬上響應並反饋。github
下一個重點特性是帶寬。因爲帶寬限制這樣的存在,在網絡通訊中雙方若是處於帶寬限制不對等的狀況下,數據包接收慢的一方會由於來不及接收而產生丟包,致使發送方數據重發從而耗費了更多的網絡資源,因此只有在雙方帶寬對等時才能到達網絡最大利用率。web
爲何傳統的 HTTP 在這方面會表現得如此差強人意。與網站的交互須要同時傳輸多種內容,而 HTTP 使用單獨的 TCP 沒法達到這一目的,所以瀏覽器會和 Web 服務器進行多個鏈接 (通常爲 6)。可這又破壞了對帶寬的估計,所以每一個 TCP 鏈接都試圖獨立地執行,就好像其餘鏈接不存在同樣。SPDY 經過多路複用的特性解決了這一問題,它將瀏覽器/服務器之間的多個交互與單個帶寬計算結合在一塊兒。chrome
QUIC 擴展了這種多路複用方式,促使在瀏覽器/服務器之間的多個交互處理變得更加簡單,這不會致使交互之間彼此阻塞,這須要通用的帶寬估算。從用戶的角度來看,這將使交互更加順暢,同時減小路由擁塞的用戶體驗。編程
如今咱們討論一下 user-mode stacks。這是來自於 TCP 的問題,尤爲是在服務器上的表現,TCP 鏈接由操做系統內核處理,而服務自己運行在用戶模式。跨內核/用戶模式邊界操做資源會致使性能問題。追蹤大量 TCP 鏈接會致使可伸縮性問題。有些人嘗試將服務器放入內核來避免過分使用的狀況,這顯然不是好主意。由於它會破壞操做系統的穩定性。個人解決方案是使用 BlackICE IPS 和 masscan,這是一個用戶模式驅動的硬件。從網絡芯片中直接獲取數據包到用戶模式進程,繞過內核 (參閱 PoC||GTFO #15),使用自定義的 TCP 堆棧。這幾年在 DPDK kit 中開始流行起來。後端
但在沒有用戶模式驅動的狀況下,將 TCP 遷移到 UDP 也會帶來相同的性能提高。與調用熟悉的 recv() 函數一次接收單個數據包不一樣,你能夠調用 recvmmsg() 來同時接收一組 UDP 數據包。它仍然是一個內核/用戶模式轉換的狀況,但在同時收到一百個包進行分攤比對每一個包進行轉換要好得多。
在個人測試中,使用典型的 recv() 函數限制每秒爲 5 十萬個 UDP 數據包,但使用 recvmmsg() 和其餘一些優化手段(使用 RSS 的多核),在低端四核服務器上每秒能夠獲取 5 百萬個 UDP 數據包。這是因爲每一個核都帶有良好的可伸縮性,移動到有 64 個核的強大服務器應該會進一步改善結果。
順便說一句,「RSS」 是網絡硬件的一個特性,它將傳入的數據包分紅多個接收隊列。多核可伸縮性的最大問題是當兩個 CPU 內核須要同時讀取/修改同一件事時,共享相同的 UDP 數據包隊列會變成最大的瓶頸。所以,Intel 首先和其餘以太網供應商增長了 RSS,使每一個核都有本身的非共享數據包隊列。Linux 和其餘操做系統升級了 UDP,以支持單個套接字(SO_REUSEPORT)的多個文件描述符來處理多個隊列。如今,QUIC 利用這些進步,容許每一個核管理本身的 UDP 數據包流,而不存在與其餘 CPU 核共享東西的可伸縮性問題。我之因此說起,是由於我曾在 2000 年時,與 Intel 硬件工程師討論過創建多個分組隊列的問題。這是一個常見的問題,也是一個顯而易見的解決方案,在過去的二十年裏,看到它的進展一直頗有趣,知道它以 HTTP/3 的形式出如今頂層。若是沒有網絡硬件中的 RSS,QUIC 也不太可能會成爲標準。
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。應該有像應用程序服務元素之類的能以標準方式爲不一樣的應用程序處理像文件傳輸和消息傳遞之類的操做。尤爲是包括 Go、QUIC、protobufs 等在 Google 的驅動下,人們會愈來愈傾向於這種模式。
我之因此會提到這一點,是由於 Google 和 微軟之間造成了鮮明的對比。微軟擁有一個流行的操做系統,因此它的創新是有它在該操做系統內所能作的事情驅動的。Google 的創新是由它能在操做系統上安裝的東西所驅動的。還有 Facebook 和 Amazon 自己,它們必須在谷歌所提供給他們的堆棧之上(或者外部)進行創新。世界上排名前五位的公司依次是 Apple、Google、Microsoft、Amazon、Facebook,所以每一個公司推進創新的位置都很重要。
結論
當 TCP 在 20 世紀 70 年代被建立時,它是偉大的。它所處理的操做,諸如擁塞,遠遠好過相互競爭的協議。儘管人們聲稱 IPv4 沒有預料到超過 40 億個地址的事情,但它比 70 年代和 80 年代的競爭設計要好得多。IPv4 升級到 IPv6 很大程度上維持了 IP 的發展。相似的,TCP 升級到 QUIC 也延續了 TCP 的發展,不一樣的是在於它是爲了知足現代需求而進行的擴展。而使人驚訝的,TCP 居然能夠在一直未升級的狀態下維持了這麼長時間還仍在被使用着。
若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。
掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。