1. 程式人生 > 實用技巧 >HTTP / 2常見問題

HTTP / 2常見問題

這些是有關HTTP / 2的常見問題。

一般的問題

為什麼要修改HTTP?

HTTP / 1.1在Web上已經服務了15多年,但是它的年齡正在開始顯現。

載入網頁比以往任何時候都需要更多資源(請參閱HTTP存檔的頁面大小統計資訊),並且要高效地載入所有這些資產非常困難,因為HTTP實際上每個TCP連線只允許一個未完成的請求。

過去,瀏覽器使用多個TCP連線來發出並行請求。但是,這是有侷限性的。如果使用的連線過多,則會適得其反(TCP擁塞控制被有效地取消,導致擁塞事件損害效能和網路),並且從根本上講是不公平的(因為瀏覽器佔用的資源超過了其網路資源的份額)。

同時,大量請求意味著“線上”上有大量重複資料。

這兩個因素都意味著HTTP / 1.1請求具有與之相關的大量開銷。如果提出過多的請求,則會影響效能。

這使該行業進入了一種被認為是“最佳實踐”的地方,可以進行諸如拼寫,資料:內聯,域分片和連線之類的事情。

這些黑客行為表明協議本身存在潛在問題,使用時會自行引發許多問題。

誰製作了HTTP / 2?

HTTP / 2是由IETFHTTP工作組開發的,該工作組維護HTTP協議。它由許多HTTP實施者,使用者,網路運營商和HTTP專家組成。

請注意,雖然我們的郵件列表託管在W3C網站上,但這不是W3C的努力。但是,Tim Berners-Lee和W3C TAG與WG的工作保持同步。

大量的人為這項工作做出了貢獻,但是最活躍的參與者包括Firefox,Chrome,Twitter,Microsoft的HTTP堆疊,Curl和Akamai等“大型”專案的工程師,以及Python等語言的HTTP實現者,Ruby和NodeJS。

要了解有關參加IETF的更多資訊,請參見IETF的Tao您還可以在Github的貢獻者圖中瞭解誰為規範做出了貢獻,以及誰在我們的實現列表中實現

與SPDY有什麼關係?

當SPDY逐漸受到實現者(例如Mozilla和nginx)的青睞時,首次討論了HTTP / 2,並顯示出對HTTP / 1.x的重大改進。

在徵求建議書和進行選擇過程之後,選擇SPDY / 2作為HTTP / 2的基礎。此後,根據工作組的討論和實施者的反饋,進行了許多更改。

在整個過程中,SPDY的核心開發人員都參與了HTTP / 2的開發,包括Mike Belshe和Roberto Peon。

2015年2月,Google宣佈了計劃刪除對SPDY的支援,而改為使用HTTP / 2。

是HTTP / 2.0還是HTTP / 2?

工作組決定刪除次版本(“ .0”),因為它在HTTP / 1.x中引起了很多混亂。

換句話說,HTTP版本表示線路相容性,而不表示功能集或“營銷”。

HTTP / 1.x的主要區別是什麼?

在較高級別,HTTP / 2:

  • 是二進位制的,而不是文字的
  • 完全多路複用,而不是有序和阻塞
  • 因此可以使用一個連線進行並行處理
  • 使用頭壓縮​​來減少開銷
  • 允許伺服器主動將響應“推送”到客戶端快取

為什麼是HTTP / 2二進位制檔案?

與諸如HTTP / 1.x之類的文字協議相比,二進位制協議解析起來更高效,更“緊湊”,並且最重要的是,它們比二進位制協議更不容易出錯,因為它們通常具有許多“幫助”功能。 ”,例如空白處理,大寫,行尾,空白行等。

例如,HTTP / 1.1定義了四種不同的解析訊息的方式在HTTP / 2中,只有一個程式碼路徑。

確實不能通過telnet使用HTTP / 2,但是我們已經有了一些工具支援,例如Wireshark外掛

為什麼要對HTTP / 2進行多路複用?

HTTP / 1.x存在一個稱為“行頭阻止”的問題,其中實際上一次只能在一個連線上處理一個請求。

HTTP / 1.1嘗試通過流水線修復此問題,但並不能完全解決問題(較大或較慢的響應仍可能阻止其他問題在後)。此外,由於許多中介和伺服器未正確處理管道,因此發現管道部署非常困難。

這迫使客戶使用多種試探法(通常是猜測法)來確定什麼請求在什麼時候對原點進行哪個連線;由於頁面通常載入可用連線數的10倍(或更多),因此這可能嚴重影響效能,通常導致被阻止請求的“瀑布”。

複用通過允許同時傳送多個請求和響應訊息來解決這些問題。甚至有可能將一條訊息的一部分與另一條訊息混合在一起。

反過來,這允許客戶端在每個起點僅使用一個連線來載入頁面。

為什麼只有一個TCP連線?

使用HTTP / 1,瀏覽器在每個來源之間開啟四個到八個連線。由於許多站點使用多個來源,因此這可能意味著單個頁面載入會開啟三十多個連線。

一個應用程式開啟如此多的連線會同時打破許多建立TCP的假設。由於每個連線都會在響應中引發大量資料,因此存在中間網路中的緩衝區真正溢位的真正風險,從而導致擁塞事件並重新傳輸。

此外,使用如此多的連線會不公平地壟斷網路資源,將它們從其他效能更好的應用程式(例如VoIP)“竊取”。

伺服器推送的好處是什麼?

當瀏覽器請求頁面時,伺服器會在響應中傳送HTML,然後需要等待瀏覽器解析HTML併發出對所有嵌入式資產的請求,然後才能開始傳送JavaScript,影象和CSS。

伺服器推送可以通過“推送”它認為客戶端將需要的響應到其快取中來潛在地使伺服器避免這種往返延遲。

但是,“推送”響應不是“神奇的” –如果使用不正確,可能會損害效能。正確使用Server Push是正在進行的實驗和研究領域。

為什麼我們需要頭壓縮?

Mozilla的Patrick McManus通過計算平均頁面載入量的標題效果生動地展示了這一點。

如果您假設一個頁面包含大約80個資產(在當今的Web中是保守的),並且每個請求具有1400位元組的標頭(再次,這並不罕見,這要歸功於Cookie,Referer等),它至少需要7-8往返以使標頭“線上”顯示。這不包括響應時間-只是使它們脫離客戶端。

這是因為TCP的慢啟動機制,該機制根據已確認的資料包數量在新連線上加快資料包的傳送速度-有效地限制了前幾次往返可傳送的資料包數量。

相比之下,即使對報頭進行適度的壓縮,這些請求也可以在一次往返(甚至一個數據包)內進入網路。

這種開銷是相當大的,尤其是考慮到對移動客戶端的影響時,即使在良好條件下,移動客戶端的往返延遲通常也要幾百毫秒。

為什麼選擇HPACK?

SPDY / 2建議在每個方向上使用單個GZIP上下文進行標頭壓縮,該方法易於實現且效率很高。

從那時起,針對加密內部使用流壓縮(例如GZIP)的重大攻擊已得到記錄。犯罪

使用CRIME,有能力將資料注入加密流中的攻擊者可以“探測”明文並恢復它。由於這是Web,因此JavaScript使這成為可能,並且演示了使用CRIME來為TLS保護的HTTP資源恢復cookie和身份驗證令牌。

結果,我們無法使用GZIP壓縮。沒有找到適合該用例並且可以安全使用的其他演算法,我們建立了一種新的,特定於報頭的壓縮方案,該方案以粗粒度執行;由於HTTP標頭通常在訊息之間不更改,因此仍然可以提供合理的壓縮效率,並且更加安全。

HTTP / 2可以使Cookie(或其他標頭)更好嗎?

這項工作被安排用於修訂有線協議,即,如何將HTTP標頭,方法等“置於網路上”,而不改變HTTP的語義。

這是因為HTTP被廣泛使用。如果我們使用此版本的HTTP引入一種新的狀態機制(已經討論過一個示例)或更改了核心方法(很幸運,尚未提出該提議),則意味著新協議與現有Web不相容。 。

特別是,我們希望能夠在不丟失任何資訊的情況下從HTTP / 1轉換為HTTP / 2。如果我們開始“清理”標頭檔案(大多數人會同意HTTP標頭檔案很亂),我們將與許多現有的Web發生互操作性問題。

這樣做只會導致反對採用新協議。

綜上所述,HTTP工作組負責所有HTTP,而不僅僅是HTTP / 2。這樣,我們可以開發與版本無關的新機制,只要它們與現有Web向後相容即可。

非瀏覽器的HTTP使用者呢?

如果非瀏覽器應用程式已經在使用HTTP,則它們也應該能夠使用HTTP / 2。

早期的反饋是HTTP / 2具有HTTP“ API”的良好效能特徵,因為API不需要在設計中考慮諸如請求開銷之類的問題。

話雖如此,我們正在考慮的改進的主要焦點是典型的瀏覽用例,因為這是該協議的核心用例。

我們的章程對此表示:

The resulting specification(s) are expected to meet these goals for common
existing deployments of HTTP; in particular, Web browsing (desktop and
mobile), non-browsers ("HTTP APIs"), Web serving (at a variety of scales), and
intermediation (by proxies, corporate firewalls, "reverse" proxies and Content
Delivery Networks). Likewise, current and future semantic extensions to
HTTP/1.x (e.g., headers, methods, status codes, cache directives) should be
supported in the new protocol.

Note that this does not include uses of HTTP where non-specified behaviours
are relied upon (e.g., connection state such as timeouts or client affinity,
and "interception" proxies); these uses may or may not be enabled by the final
product.

HTTP / 2是否需要加密?

否。經過廣泛討論,工作組尚未達成共識,要求對新協議使用加密(例如TLS)。

但是,一些實現已宣告,僅當通過加密連線使用HTTP / 2時,它們才會支援HTTP / 2,並且當前沒有瀏覽器支援未加密的HTTP / 2。

HTTP / 2如何提高安全性?

HTTP / 2定義了必需的TLS配置檔案;這包括版本,密碼套件黑名單和使用的副檔名。

有關詳細資訊,請參見規格

還討論了其他機制,例如對HTTP:// URL使用TLS(所謂的“機會加密”);參見RFC 8164

我現在可以使用HTTP / 2嗎?

在瀏覽器中,Edge,Safari,Firefox和Chrome的最新版本支援HTTP / 2。其他基於Blink的瀏覽器也將支援HTTP / 2(例如Opera和Yandex Browser)。有關更多詳細資訊,請參見

還有一些可用的伺服器(包括AkamaiGoogleTwitter的主要站點提供的beta支援),以及可以部署和測試的許多開源實現。

有關更多詳細資訊,請參見實現列表

HTTP / 2會取代HTTP / 1.x嗎?

工作組的目標是HTTP / 1.x的典型用法可以使用HTTP / 2並看到一些好處。話雖如此,我們不能強迫世界遷移,並且由於人們部署代理和伺服器的方式,HTTP / 1.x可能仍會使用很長時間。

會有HTTP / 3嗎?

如果HTTP / 2引入的協商機制執行良好,則應該有可能比過去更輕鬆地支援HTTP的新版本。

實施問題

為什麼圍繞HEADERS框架上的Continuation的規則?

存在連續性是因為單個值(例如Set-Cookie)可能超過16KiB-1,這意味著它無法放入單個幀中。已確定處理此問題的最不容易出錯的方法是要求所有標頭資料都以背對背幀的形式出現,這使得解碼和緩衝區管理更加容易。

HPACK狀態的最小或最大大小是多少?

接收器始終控制HPACK中使用的記憶體量,並且可以將其最小設定為零,最大值與SETTINGS幀中的最大可表示整數(當前為2 ^ 32-1)有關。

如何避免保持HPACK狀態?

將SETTINGS幀設定狀態大小(SETTINGS_HEADER_TABLE_SIZE)傳送為零,然後傳送所有流RST,直到接收到設定了ACK位的SETTINGS幀為止。

為什麼只有一個壓縮/流控制上下文?

簡單。

最初的提議具有流組,它們將共享上下文,流控制等。雖然這將使代理受益(以及代理使用者的經驗),但這樣做卻增加了相當的複雜性。我們決定先從簡單的事情開始,看看它有多痛苦,並在將來的協議修訂版中解決該痛苦(如果有的話)。

為什麼HPACK中有EOS符號?

HPACK的霍夫曼編碼,出於CPU效率和安全性的考慮,將霍夫曼編碼的字串填充到下一個位元組邊界;對於任何特定的字串,可能需要0-7位之間的填充。

如果考慮隔離霍夫曼解碼,則任何比所需填充長的符號都可以工作;但是,HPACK的設計允許按位元組比較霍夫曼編碼的字串。通過要求將EOS符號的位用於填充,我們確保使用者可以對霍夫曼編碼的字串進行位元組比較,以確定是否相等。反過來,這意味著可以解釋許多標頭,而無需對其進行霍夫曼解碼。

是否可以在不實現HTTP / 1.1的情況下實現HTTP / 2?

是的,主要是。

對於TLS(h2)上的HTTP / 2,如果您未實現http1.1ALPN識別符號,則無需支援任何HTTP / 1.1功能。

對於基於TCP(h2c)的HTTP / 2,您需要實施初始升級請求。

h2c-僅客戶端將需要生成“ *”的OPTIONS請求或“ /”的HEAD請求,這些請求相當安全且易於構造。希望僅實現HTTP / 2的客戶端將需要將沒有101狀態程式碼的HTTP / 1.1響應視為錯誤。

h2c-僅伺服器可以接受包含“升級標頭”欄位和固定101響應的請求。沒有h2c升級令牌的請求可以通過包含升級標頭欄位的505(不支援HTTP版本)狀態程式碼拒絕。不希望處理HTTP / 1.1響應的伺服器應在傳送連線序言後立即拒絕帶有REFUSED_STREAM錯誤程式碼的流1,以鼓勵客戶端通過升級的HTTP / 2連線重試請求。

第5.3.2節中的優先順序示例不正確嗎?

否。流B的權重為4,流C的權重為12。要確定這些流中的每一個接收的可用資源的比例,請將所有權重相加(16),然後將每個流的權重除以總權重。因此,流B獲得四分之一的可用資源,流C獲得四分之三的可用資源。因此,如規範所述,流B理想地接收分配給流C的資源的三分之一

我的HTTP / 2連線是否需要TCP_NODELAY?

應該是。即使對於僅使用單個流下載大量資料的客戶端實現,仍然需要一些資料包以相反的方向傳送回去,以實現最大的傳輸速度。如果未設定TCP_NODELAY(仍允許Nagle演算法),則傳出資料包可能會保留一段時間,以便允許它們與後續資料包合併。

例如,在這樣的資料包告訴對方有更多可用視窗傳送資料的情況下,將其傳送延遲數毫秒(或更長時間)可能會對高速連線產生嚴重影響。

部署問題

如果HTTP / 2已加密,如何除錯?

有很多方法可以訪問應用程式資料,但是最簡單的方法是將NSS鍵盤記錄與Wireshark外掛(包含在最新開發版本中)結合使用。Firefox和Chrome均可使用。

如何使用HTTP / 2伺服器推送?

HTTP / 2伺服器推送允許伺服器無需等待請求即可向客戶端提供內容。這可以改善檢索資源的時間,尤其是對於具有大頻寬延遲產品的連線,其中網路往返時間包括花費在資源上的大部分時間。

推送基於請求內容而變化的資源可能是不明智的。當前,瀏覽器僅在其他情況下才使用推送請求,否則它們將發出匹配請求(請參閱RFC 7234的第4節)。

某些快取不考慮所有請求標頭欄位中的變化,即使它們在Vary標頭欄位中列出也是如此為了最大化接受推送的資源的可能性,最好避免內容協商。accept-encoding快取廣泛遵循基於標頭欄位的內容協商,但是可能無法很好地支援其他標頭欄位。