HTTP3 為什麼比 HTTP2 靠譜?| 技術頭條

2021-01-10 CSDN

作者 | 浪裡行舟

責編 | 郭芮

HTTP/2 相比於 HTTP/1,可以說是大幅度提高了網頁的性能,只需要升級到該協議就可以減少很多之前需要做的性能優化工作,當然兼容問題以及如何優雅降級應該是國內還不普遍使用的原因之一。

雖然 HTTP/2 提高了網頁的性能,但是並不代表它已經是完美的了,HTTP/3 就是為了解決 HTTP/2 所存在的一些問題而被推出來的。

HTTP協議

HTTP協議是HyperText Transfer Protocol(超文本傳輸協議)的縮寫,它是網際網路上應用最為廣泛的一種網絡協議。所有的WWW文件都必須遵守這個標準。

伴隨著計算機網絡和瀏覽器的誕生,HTTP1.0也隨之而來,處於計算機網絡中的應用層,HTTP是建立在TCP協議之上,所以HTTP協議的瓶頸及其優化技巧都是基於TCP協議本身的特性,例如TCP建立連接的3次握手和斷開連接的4次揮手以及每次建立連接帶來的RTT延遲時間。

HTTP/1.x的缺陷

連接無法復用:連接無法復用會導致每次請求都經歷三次握手和慢啟動。三次握手在高延遲的場景下影響較明顯,慢啟動則對大量小文件請求影響較大(沒有達到最大窗口請求就被終止)。

HTTP/1.0傳輸數據時,每次都需要重新建立連接,增加延遲。HTTP/1.1雖然加入keep-alive可以復用一部分連接,但域名分片等情況下仍然需要建立多個connection,耗費資源,給伺服器帶來性能壓力。Head-Of-Line Blocking(HOLB):導致帶寬無法被充分利用,以及後續健康請求被阻塞。HOLB是指一系列包(package)因為第一個包被阻塞;當頁面中需要請求很多資源的時候,HOLB(隊頭阻塞)會導致在達到最大請求數量時,剩餘的資源需要等待其他資源請求完成後才能發起請求。

HTTP 1.0:下個請求必須在前一個請求返回後才能發出,request-response對按序發生。顯然,如果某個請求長時間沒有返回,那麼接下來的請求就全部阻塞了。HTTP 1.1:嘗試使用 pipeling 來解決,即瀏覽器可以一次性發出多個請求(同個域名,同一條 TCP 連結)。但 pipeling 要求返回是按序的,那麼前一個請求如果很耗時(比如處理大圖片),那麼後面的請求即使伺服器已經處理完,仍會等待前面的請求處理完才開始按序返回。所以,pipeling 只部分解決了 HOLB。

如上圖所示,紅色圈出來的請求就因域名連結數已超過限制,而被掛起等待了一段時間。

協議開銷大: HTTP1.x在使用時,header裡攜帶的內容過大,在一定程度上增加了傳輸的成本,並且每次請求header基本不怎麼變化,尤其在移動端增加用戶流量。

安全因素:HTTP1.x在傳輸數據時,所有傳輸的內容都是明文,客戶端和伺服器端都無法驗證對方的身份,這在一定程度上無法保證數據的安全性。

SPDY 協議

因為HTTP/1.x的問題,我們會引入雪碧圖、將小圖內聯、使用多個域名等等的方式來提高性能。不過這些優化都繞開了協議,直到2009年,谷歌公開了自行研發的 SPDY 協議,主要解決HTTP/1.1效率不高的問題。谷歌推出SPDY,才算是正式改造HTTP協議本身。降低延遲,壓縮header等等,SPDY的實踐證明了這些優化的效果,也最終帶來HTTP/2的誕生。

SPDY 協議在Chrome瀏覽器上證明可行以後,就被當作 HTTP/2 的基礎,主要特性都在 HTTP/2 之中得到繼承。

HTTP/2 簡介

2015年,HTTP/2 發布。HTTP/2是現行HTTP協議(HTTP/1.x)的替代,但它不是重寫,HTTP方法/狀態碼/語義都與HTTP/1.x一樣。HTTP/2基於SPDY3,專注於性能,最大的一個目標是在用戶和網站間只用一個連接(connection)。

HTTP/2由兩個規範(Specification)組成:

Hypertext Transfer Protocol version 2 - RFC7540HPACK - Header Compression for HTTP/2 - RFC7541

HTTP/2 新特性

1.二進位傳輸

HTTP/2 採用二進位格式傳輸數據,而非 HTTP 1.x 的文本格式,二進位協議解析起來更高效。HTTP / 1 的請求和響應報文,都是由起始行,首部和實體正文(可選)組成,各部分之間以文本換行符分隔。HTTP/2 將請求和響應數據分割為更小的幀,並且它們採用二進位編碼。

接下來我們介紹幾個重要的概念:

流:流是連接中的一個虛擬信道,可以承載雙向的消息;每個流都有一個唯一的整數標識符(1、2…N);消息:是指邏輯上的 HTTP 消息,比如請求、響應等,由一或多個幀組成;幀:HTTP 2.0 通信的最小單位,每個幀包含幀首部,至少也會標識出當前幀所屬的流,承載著特定類型的數據,如 HTTP 首部、負荷等等。

HTTP/2 中,同域名下所有通信都在單個連接上完成,該連接可以承載任意數量的雙向數據流。每個數據流都以消息的形式發送,而消息又由一個或多個幀組成。多個幀之間可以亂序發送,根據幀首部的流標識可以重新組裝。

2.多路復用

在 HTTP/2 中引入了多路復用的技術。多路復用很好的解決了瀏覽器限制同一個域名下的請求數量的問題,同時也接更容易實現全速傳輸,畢竟新開一個 TCP 連接都需要慢慢提升傳輸速度。

大家可以通過 該連結 直觀感受下 HTTP/2 比 HTTP/1 到底快了多少。

在 HTTP/2 中,有了二進位分幀之後,HTTP /2 不再依賴 TCP 連結去實現多流並行了,在 HTTP/2中:

同域名下所有通信都在單個連接上完成;單個連接可以承載任意數量的雙向數據流;數據流以消息的形式發送,而消息又由一個或多個幀組成,多個幀之間可以亂序發送,因為根據幀首部的流標識可以重新組裝。這一特性,使性能有了極大提升:

同個域名只需要佔用一個 TCP 連接,使用一個連接並行發送多個請求和響應,消除了因多個 TCP 連接而帶來的延時和內存消耗;並行交錯地發送多個請求,請求之間互不影響;並行交錯地發送多個響應,響應之間互不幹擾;在HTTP/2中,每個請求都可以帶一個31bit的優先值,0表示最高優先級, 數值越大優先級越低。有了這個優先值,客戶端和伺服器就可以在處理不同的流時採取不同的策略,以最優的方式發送流、消息和幀。

如上圖所示,多路復用的技術可以只通過一個 TCP 連接就可以傳輸所有的請求數據。

3.Header 壓縮

在 HTTP/1 中,我們使用文本的形式傳輸 header,在 header 攜帶 cookie 的情況下,可能每次都需要重複傳輸幾百到幾千的字節。

為了減少這塊的資源消耗並提升性能, HTTP/2對這些首部採取了壓縮策略:

HTTP/2在客戶端和伺服器端使用「首部表」來跟蹤和存儲之前發送的鍵-值對,對於相同的數據,不再通過每次請求和響應發送;首部表在HTTP/2的連接存續期內始終存在,由客戶端和伺服器共同漸進地更新;每個新的首部鍵-值對要麼被追加到當前表的末尾,要麼替換表中之前的值。例如下圖中的兩個請求,請求一發送了所有的頭部欄位,第二個請求則只需要發送差異數據,這樣可以減少冗餘數據,降低開銷。

4.Server Push

Server Push即服務端能通過push的方式將客戶端需要的內容預先推送過去,也叫「cache push」。

可以想像以下情況,某些資源客戶端是一定會請求的,這時就可以採取服務端 push 的技術,提前給客戶端推送必要的資源,這樣就可以相對減少一點延遲時間。當然在瀏覽器兼容的情況下你也可以使用 prefetch。

例如服務端可以主動把JS和CSS文件推送給客戶端,而不需要客戶端解析HTML時再發送這些請求。

服務端可以主動推送,客戶端也有權利選擇是否接收。如果服務端推送的資源已經被瀏覽器緩存過,瀏覽器可以通過發送RST_STREAM幀來拒收。主動推送也遵守同源策略,換句話說,伺服器不能隨便將第三方資源推送給客戶端,而必須是經過雙方確認才行。

HTTP/3 新特性

1.HTTP/3簡介

雖然 HTTP/2 解決了很多之前舊版本的問題,但是它還是存在一個巨大的問題,主要是底層支撐的 TCP 協議造成的。

上文提到 HTTP/2 使用了多路復用,一般來說同一域名下只需要使用一個 TCP 連接。但當這個連接中出現了丟包的情況,那就會導致 HTTP/2 的表現情況反倒不如 HTTP/1 了。

因為在出現丟包的情況下,整個 TCP 都要開始等待重傳,也就導致了後面的所有數據都被阻塞了。但是對於 HTTP/1.1 來說,可以開啟多個 TCP 連接,出現這種情況反到只會影響其中一個連接,剩餘的 TCP 連接還可以正常傳輸數據。

那麼可能就會有人考慮到去修改 TCP 協議,其實這已經是一件不可能完成的任務了。因為 TCP 存在的時間實在太長,已經充斥在各種設備中,並且這個協議是由作業系統實現的,更新起來不大現實。

基於這個原因,Google 就更起爐灶搞了一個基於 UDP 協議的 QUIC 協議,並且使用在了 HTTP/3 上,HTTP/3 之前名為 HTTP-over-QUIC,從這個名字中我們也可以發現,HTTP/3 最大的改造就是使用了 QUIC。

QUIC 雖然基於 UDP,但是在原本的基礎上新增了很多功能,接下來我們重點介紹幾個QUIC新功能。

2.QUIC新功能

0-RTT通過使用類似 TCP 快速打開的技術,緩存當前會話的上下文,在下次恢復會話的時候,只需要將之前的緩存傳遞給服務端驗證通過就可以進行傳輸了。0RTT 建連可以說是 QUIC 相比 HTTP2 最大的性能優勢。那什麼是 0RTT 建連呢?

這裡面有兩層含義:

1.傳輸層 0RTT 就能建立連接。

2.加密層 0RTT 就能建立加密連接。

上圖左邊是 HTTPS 的一次完全握手的建連過程,需要 3 個 RTT。就算是會話復用也需要至少 2 個 RTT。

而 QUIC 呢?由於建立在 UDP 的基礎上,同時又實現了 0RTT 的安全握手,所以在大部分情況下,只需要 0 個 RTT 就能實現數據發送,在實現前向加密的基礎上,並且 0RTT 的成功率相比 TLS 的會話記錄單要高很多。

多路復用雖然 HTTP/2 支持了多路復用,但是 TCP 協議終究是沒有這個功能的。QUIC 原生就實現了這個功能,並且傳輸的單個數據流可以保證有序交付且不會影響其他的數據流,這樣的技術就解決了之前 TCP 存在的問題。

同HTTP2.0一樣,同一條 QUIC連接上可以創建多個stream,來發送多個HTTP請求,但是,QUIC是基於UDP的,一個連接上的多個stream之間沒有依賴。比如下圖中stream2丟了一個UDP包,不會影響後面跟著 Stream3 和 Stream4,不存在 TCP 隊頭阻塞。雖然stream2的那個包需要重新傳,但是stream3、stream4的包無需等待,就可以發給用戶。

另外QUIC 在移動端的表現也會比 TCP 好。因為 TCP 是基於 IP 和埠去識別連接的,這種方式在多變的移動端網絡環境下是很脆弱的。但是 QUIC 是通過 ID 的方式去識別一個連接,不管你網絡環境如何變化,只要 ID 不變,就能迅速重連上。

加密認證的報文TCP 協議頭部沒有經過任何加密和認證,所以在傳輸過程中很容易被中間網絡設備篡改,注入和竊聽。比如修改序列號、滑動窗口。這些行為有可能是出於性能優化,也有可能是主動攻擊。

但是 QUIC 的 packet 可以說是武裝到了牙齒。除了個別報文比如 PUBLIC_RESET 和 CHLO,所有報文頭部都是經過認證的,報文 Body 都是經過加密的。

這樣只要對 QUIC 報文任何修改,接收端都能夠及時發現,有效地降低了安全風險。

如上圖所示,紅色部分是 Stream Frame 的報文頭部,有認證。綠色部分是報文內容,全部經過加密。

向前糾錯機制QUIC協議有一個非常獨特的特性,稱為向前糾錯 (Forward Error Correction,FEC),每個數據包除了它本身的內容之外,還包括了部分其他數據包的數據,因此少量的丟包可以通過其他包的冗餘數據直接組裝而無需重傳。向前糾錯犧牲了每個數據包可以發送數據的上限,但是減少了因為丟包導致的數據重傳,因為數據重傳將會消耗更多的時間(包括確認數據包丟失、請求重傳、等待新數據包等步驟的時間消耗)。

假如說這次我要發送三個包,那麼協議會算出這三個包的異或值並單獨發出一個校驗包,也就是總共發出了四個包。當出現其中的非校驗包丟包的情況時,可以通過另外三個包計算出丟失的數據包的內容。當然這種技術只能使用在丟失一個包的情況下,如果出現丟失多個包就不能使用糾錯機制了,只能使用重傳的方式了。

總結

HTTP/1.x 有連接無法復用、隊頭阻塞、協議開銷大和安全因素等多個缺陷;HTTP/2 通過多路復用、二進位流、Header 壓縮等等技術,極大地提高了性能,但是還是存在著問題的;QUIC 基於 UDP 實現,是 HTTP/3 中的底層支撐協議,該協議基於 UDP,又取了 TCP 中的精華,實現了即快又可靠的協議。

作者:浪裡行舟,碩士研究生,專注於前端,運營有個人公眾號前端工匠,致力於打造適合初中級工程師能夠快速吸收的一系列優質文章。聲明:本文為CSDN技術頭條專欄原創投稿,未經允許請勿轉載。歡迎大家通過以下方式聯繫投稿。

相關焦點

  • Go中的HTTP請求之——HTTP1.1請求流程分析
    大綱前言http是目前應用最為廣泛, 也是程式設計師接觸最多的協議之一。今天筆者站在GoPher的角度對http1.1的請求流程進行全面的分析。因為本篇主旨是http1.1,所以我們直接看http1.1的執行分支。根據源碼中的注釋和實際的debug結果,獲取到連接後, 會繼續調用pconn.roundTrip。(*Transport).getConn筆者認為這一步在http請求中是非常核心的一個步驟,因為只有和server端建立連接後才能進行後續的通信。
  • 有了HTTP,為什麼還要RPC?
    好,知道了網絡的分層模型以後我們可以更好地理解為什麼 RPC 服務相比 HTTP 服務要 Nice 一些!RPC 服務從三個角度來介紹 RPC 服務,分別是:RPC 架構先說說 RPC 服務的基本架構吧。
  • 2021青島衛生專業技術資格考試報名入口http://www.21wecan.com
    2021青島衛生專業技術資格考試報名入口http://www.21wecan.com 2021年山東衛生專業技術資格考試公告已經發布,報名時間:2020年12月29日-2021年1月11日,考試時間:4月10、11、 17、18日。
  • 一次完整的http請求詳解
    Http請求的一次詳解:(1) 客戶端輸入URL(2) 客戶端檢測緩存:有緩存且較新,客戶端直接讀取本地緩存進行資源展示有緩存但是不新,準備http請求包,發送至服務端進行緩存校驗備註:http1.0中Expire、http1.1中是Cache-Control根據發起http請求: 請求報文包含:
  • 淺度測評:requests、aiohttp、httpx 我應該用哪一個?
    在 Python 眾多的 HTTP 客戶端中,最有名的莫過於requests、aiohttp和httpx。在不藉助其他第三方庫的情況下,requests只能發送同步請求;aiohttp只能發送異步請求;httpx既能發送同步請求,又能發送異步請求。
  • Jmeter之HTTP請求與響應
    HTTP請求詳解一個http請求指從客戶端到服務端的請求信息,我們可以通過瀏覽器的F12鍵,可以看到以下信息:1.請求地址:uri>2.請求方法:HEAD,GET,POST,PUT,OPTIONS,DELETE,PATCH3.HTTP協議/版本:可以打開瀏覽器按下F12仔細查看4.請求頭
  • HTTP協議之狀態碼詳解
    在不獲取資源的情況下了解資源的情況(比如判斷其類型)2. 通過查看Response中的狀態碼, 看看某個對象是否存在3. 通過查看Header, 測試資源是否被修改了。實例:先打開Fiddler, 然後啟動瀏覽器訪問ditu.google.cn, 你會捕獲到很多204
  • Go發起HTTP2.0請求流程分析(前篇)
    http2SettingEnablePush: 告知server客戶端是否開啟push功能。http2SettingInitialWindowSize:告知server客戶端可接受的最大數據窗口是http2transportDefaultStreamFlow(4M)。
  • 通信網絡技術:RPC服務和HTTP服務的區別分析
    通信網絡技術:RPC服務和HTTP服務的區別分析 浮生憶夢 發表於 2020-11-26 13:52:51 很長時間以來都沒有怎麼好好搞清楚 RPC(即 Remote
  • HttpComponents Core 5.0.2 GA 發布
    HttpComponents Core 5.0.2 GA 發布,HttpCore 是 HTTP/1.1 和 HTTP/2 傳輸組件
  • Linux使用epoll異步發送http請求
    http是基於tcp的協議,在發送http請求之前,要先與伺服器建立tcp連接,然後才可以發送HTTP請求。HTTP請求的頭部,就是一些以\r\n分割的字符串。第一行為GET、POST方法,之後的每一行為冒號分割的鍵值對,表示http請求的一些信息。
  • Linux使用epoll控制多個socket發送http請求
    2,狀態為CONNECTING時,調用client_connect_check()函數。它判斷是否為寫事件,如果是則用getsockopt()讀取錯誤碼,然後填充http請求的緩衝區。最後,設置狀態為連接完成CONNECTED,繼續監控寫事件EPOLLOUT,等待發送數據。
  • 2020.10.26 更新一套Http格式直播源,低調速用
    playurl=http://swds2.cntv.gmzb.xyz/eltasport_twn/playlist.m3u8ELTA體育3,http://www.swzb.xyz/smart.php?playurl=http://swds2.cntv.gmzb.xyz/eltasports3_twn/playlist.m3u8ELTA體育2,http://www.swzb.xyz/smart.php?
  • Apache HTTP Server 2.4.43 發布 修復安全漏洞
    受影響版本為 Apache HTTP Server 2.4.0 至 2.4.41mod_SSL:修復 OCSP stapling 響應的內存洩漏問題詳情查看 https://downloads.apache.org/httpd/CHANGES_2.4.43下載地址:http://httpd.apache.org/download.cgiApache HTTP Server
  • IT挑戰高薪必備網絡常識-如何理解HTTP協議是無狀態的
    http 1.0中默認是關閉的,需要在http頭加入」Connection: Keep-Alive」,才能啟用Keep-Alive;http 1.1中默認啟用Keep-Alive,如果加入」Connection: close 「,才關閉,目前大部分瀏覽器都是用http1.1協議,也就是說默認都會發起Keep-Alive的連接請求了
  • 有了HTTP 協議,為什麼還要 RPC 協議,兩者有什麼區別?
    好,知道了網絡的分層模型以後我們可以更好地理解為什麼 RPC 服務相比 HTTP 服務要 Nice 一些!  為什麼這麼做?主要是為了減少客戶端這邊的 jar 包大小,因為每一次打包發布的時候,jar 包太多總是會影響效率。另外也是將客戶端和服務端解耦,提高代碼的可移植性。  2、同步調用與異步調用  什麼是同步調用?什麼是異步調用?同步調用就是客戶端等待調用執行完成並返回結果。
  • 德州2020下半年中小學教師資格考試(筆試)成績查詢入口-http://...
    德州2020下半年中小學教師資格考試(筆試)成績查詢入口-http://ntce.neea.edu.cn/ntce/ 德州2020下半年中小學教師資格考試(筆試)成績查詢入口-http://ntce.neea.edu.cn/ntce/,查詢時間為12月10日。
  • 長沙星沙人才網http://www.csxsrcw.com招教
    2014年長沙市長沙縣招聘152名中小幼教師,報名時間:2014年5月19日- 5月22日,筆試時間:2014年5月31日;報名網址:長沙星沙人才網(http://www.csxsrcw.com)。第一階段:提交報名信息1、報名時間:2014年5月19日- 5月22日(每天上午8:00-下午17:00)。
  • 如何對手機http進行抓包?Fiddler工具超好用
    下面是如何使用fiddler對手機APP進行抓包:1、fiddler手機抓包原理在本機開啟了一個http的代理伺服器,然後它會轉發所有的http請求和響應。Fiddler 是以代理web 伺服器的形式工作的,它使用代理地址:127.0.0.1,埠:8888。
  • 2020注會統一報名登錄入口官網http://cpaexam.cicpa.org.cn
    2020注會統一報名登錄入口官網http://cpaexam.cicpa.org.cn 2020-04-02 14:23:22| 來源:山東中公教育 2020注會統一登錄入口官網http://cpaexam.cicpa.org.cn