翻譯自:https://www.digitalocean.com/community/tutorials/http-1-1-vs-http-2-what-s-the-difference
本文主要使用www.DeepL.com/Translator翻譯(免費版)后修改
介紹
超文本傳輸協議,或稱HTTP,是一種應用協議,自1989年發明以來,一直是萬維網通信的事實上的標準,
從1997年HTTP/1.1的發布到最近,對該協議的修訂很少,
但在2015年,一個被稱為HTTP/2重新設計的版本投入使用,它提供了幾種減少延遲的方法,特別是在處理移動平臺和服務器密集型圖形和視頻時,
此后,HTTP/2變得越來越流行,一些估計表明,世界上大約三分之一的網站都支持它,
在這種不斷變化的情況下,網路開發人員可以從了解HTTP/1.1和HTTP/2之間的技術差異中受益,使他們能夠對不斷發展的最佳實踐作出明智和有效的決定,
閱讀本文后,你將了解HTTP/1.1和HTTP/2之間的主要區別,集中于HTTP/2為實作更有效的網路協議而采取的技術變革,
背景
為了了解HTTP/2對HTTP/1.1所做的具體改變,讓我們先高屋建瓴地看看各自的歷史發展和基本運作情況,
HTTP/1.1
由Timothy Berners-Lee在1989年開發,作為萬維網的通信標準,HTTP是一個頂級的應用協議,在客戶端計算機和本地或遠程網路服務器之間交換資訊,
在這個程序中,客戶端通過呼叫GET或POST等方法向服務器發送一個基于文本的請求,
作為回應,服務器發送一個資源,如一個HTML頁面,回傳給客戶端,
例如,假設你正在訪問一個域名為www.example.com 的網站,
當你導航到這個URL時,你電腦上的網路瀏覽器會以文本資訊的形式發送一個HTTP請求,類似于這里顯示的內容,
GET /index.html HTTP/1.1 Host: www.example.com
這個請求使用GET方法,它要求在Host:之后的主機服務器串列中獲取資料,
作為對這個請求的回應,example.com網路服務器將一個HTML頁面回傳給請求的客戶端,此外還有任何影像、樣式表或HTML中呼叫的其他資源,
請注意,在第一次呼叫資料時,并非所有的資源都回傳給客戶端,
請求和回應將在服務器和客戶端之間來回進行,直到網路瀏覽器收到所有必要的資源,在你的螢屏上呈現HTML頁面的內容,
你可以把這種請求和回應的交換看作是互聯網協議堆疊的單一應用層,位于傳輸層(通常使用傳輸控制協議,即TCP)和網路層(使用互聯網協議,即IP)之上,

關于這個堆疊的較低層次,還有很多要討論的,但為了獲得對HTTP/2的高層次理解,你只需要知道這個抽象的層模型以及HTTP在其中的地位,
通過對HTTP/1.1的基本概述,我們現在可以繼續敘述HTTP/2的早期發展,
HTTP/2
HTTP/2開始是SPDY協議,主要在谷歌開發,目的是通過使用壓縮、多路復用和優先級等技術來減少網頁加載延遲,
當IETF(互聯網工程任務組)的超文本傳輸協議作業組httpbis把標準放在一起時,這個協議成為了HTTP/2的模板,最終在2015年5月發布了HTTP/2,
從一開始,許多瀏覽器就支持這項標準化作業,包括Chrome、Opera、Internet Explorer和Safari,
自2015年以來,該協議的采用率很高,一部分是因為瀏覽器的支持,在新網站中采用率尤其高,
從技術角度來看,區分HTTP/1.1和HTTP/2的最重要特征之一是二進制框架層,它可以被認為是互聯網協議堆疊中應用層的一部分,
與HTTP/1.1相比,HTTP/2使用二進制框架層將所有訊息封裝成二進制格式,同時仍然保持HTTP的語意,如動詞、方法和頭檔案,
應用層的API仍然會以傳統的HTTP格式創建訊息,但底層會將這些訊息轉換為二進制,
這確保了在HTTP/2之前創建的網路應用在與新協議互動時可以繼續正常運行,
將訊息轉換為二進制允許HTTP/2嘗試HTTP/1.1中沒有的新的資料傳遞方式,這種對比是這兩個協議之間實際差異的根源,
下一節將看一下HTTP/1.1的交付模式,然后是HTTP/2使哪些新模式成為可能,
傳輸模型
正如上一節所提到的,HTTP/1.1和HTTP/2共享語意,
確保在這兩個協議中,服務器和客戶端之間的請求和回應作為傳統格式的訊息,使用GET和POST等熟悉的方法,到達目的地,
但是,當HTTP/1.1以純文本資訊傳輸這些資訊時,HTTP/2將這些資訊編碼為二進制,允許明顯不同的傳輸模型成為可能,
在這一節中,我們將首先簡要研究HTTP/1.1如何試圖通過其傳輸模型來優化效率,以及由此產生的問題,
然后是HTTP/2的二進制框架層的優勢,以及它如何對請求進行優先排序的描述,
HTTP/1.1--流水線和行首阻斷
客戶端在HTTP GET請求中收到的第一個回應通常不是完全呈現的頁面,
相反,它包含了請求頁面所需的額外資源的鏈接,
客戶端在下載頁面后才發現,頁面的完整呈現需要服務器提供這些額外資源,
正因為如此,客戶端將不得不發出額外的請求來檢索這些資源,
在HTTP/1.0中,客戶端不得不在每一個新的請求中中斷并重做TCP連接,這在時間和資源上都是一個昂貴的事情,
HTTP/1.1通過引入持久連接和流水線處理了這個問題,
通過持久連接,HTTP/1.1假定TCP連接應該保持開放,除非直接被告知關閉,
這使得客戶端可以沿著同一連接發送多個請求,而不需要等待每個請求的回應,從而在HTTP/1.0的基礎上大大改善了HTTP/1.1的性能,
不幸的是,這種優化策略有一個自然瓶頸,
由于多個資料包在前往同一目的地時不能相互傳遞,所以在有些情況下,排在隊首的請求如果不能檢索到它所需要的資源,就會阻塞后面的所有請求,
這就是所謂的行首(HOL)阻塞,是HTTP/1.1中優化連接效率的一個重要問題,
增加單獨的、平行的TCP連接可以緩解這個問題,但是客戶端和服務器之間可能的并發TCP連接數量是有限的,而且每個新連接都需要大量的資源,
這些問題是HTTP/2開發者的首要任務,他們提議使用上述的二進制框架層來解決這些問題,你將在下一節中了解更多的主題,
HTTP/2 - 二進制框架層的優勢
在HTTP/2中,二進制框架層對請求/回應進行編碼,并將其切割成更小的資訊包,大大提高了資料傳輸的靈活性,
讓我們仔細看看這是如何作業的,
與必須利用多個TCP連接來減少HOL阻塞的影響的HTTP/1.1相反,HTTP/2在兩臺機器之間建立了一個單一的連接物件,
在這個連接中,有多個資料流,
每個資料流由多個相似的請求/回應格式的訊息組成,
最后,這些訊息中的每一條都被分割成較小的單元,稱為幀,

在最微觀的層面上,通信通道由一堆二進制編碼的幀組成,每個幀都被標記在一個特定的流,
識別標簽允許連接在傳輸程序中交錯這些幀,并在另一端將其重新組合,
交錯的請求和回應可以并行運行,而不會阻斷后面的資訊,這個程序稱為復用,
復用解決了HTTP/1.1中的行首阻塞問題,確保沒有訊息需要等待另一個訊息完成,
這也意味著服務器和客戶端可以同時發送請求和回應,允許更大的控制和更有效的連接管理,
由于多路復用允許客戶端并行構建多個資料流,這些資料流只需要利用一個TCP連接,
每個來源有一個持久的連接,通過減少整個網路的記憶體和處理足跡,改善了HTTP/1.1,
這帶來了更好的網路和帶寬利用率,從而降低了整體運營成本,
單一的TCP連接也提高了HTTPS協議的性能,因為客戶端和服務器可以為多個請求/回應重復使用同一個安全會話,
在HTTPS中,在TLS或SSL握手期間,雙方同意在整個會話中使用一個單一的密鑰,
如果連接中斷,新的會話開始,需要一個新生成的密鑰來進行進一步的通信,
因此,維持一個單一的連接可以大大減少HTTPS性能所需的資源,
請注意,盡管HTTP/2規范沒有強制要求使用TLS層,但許多主要瀏覽器只支持HTTPS的HTTP/2,
盡管二進制框架層中固有的多路復用解決了HTTP/1.1的某些問題,但多個流等待同一資源仍然會導致性能問題,
然而,HTTP/2的設計通過使用流優先級考慮到了這一點,我們將在下一節討論這一問題,
HTTP/2 流優先級
流優先級不僅解決了請求競爭同一資源的可能問題,而且允許開發人員定制請求的相對權重,以更好地優化應用性能,
在本節中,我們將分解這種優先級的程序,以便更好地了解你如何利用HTTP/2的這一功能,
正如你現在所知,二進制框架層將訊息組織成平行的資料流,
當客戶端向服務器發送并發請求時,它可以通過給每個資料流分配1到256的權重來確定它所請求的回應的優先級,
數字越大表示優先級越高,
除此以外,客戶端還通過指定它所依賴的流的ID來說明每個流對另一個流的依賴性,
如果省略了父識別符號,該流就被認為是依賴于根流,
這在下圖中得到了說明,

在圖中,通道包含六個流,每個流都有一個唯一的ID,并與一個特定的權重相關,
流1沒有與之相關的父ID,默認與根節點相關,
所有其他的流都有一些父ID標記,
每個流的資源分配將基于它們持有的權重和它們需要的依賴關系,
例如,流5和流6,在圖中被分配了相同的權重和相同的父流,將有相同的資源分配優先級,
服務器使用這些資訊來創建一個依賴樹,這使得服務器能夠確定請求檢索其資料的順序,基于上圖中的資料流,依賴樹將如下所示,

在這個依賴樹中,流1依賴于根流,沒有從根流派生出來的其他流,所以所有可用的資源都將分配給流1,領先于其他流,
由于該樹表明流2依賴于流1的完成,所以流2在流1的任務完成之前不會進行,
現在,讓我們看一下流3和流4,這兩個流都依賴于流2,
與流1的情況一樣,流2將在流3和流4之前獲得所有可用的資源,
在流2完成其任務后,流3和流4將獲得資源;
如其權重所示,這些資源按2:4的比例分配,結果是流4獲得了更多的資源,
最后,當流3完成時,流5和流6將以相等的部分獲得可用的資源,
這可能發生在流4完成其任務之前,盡管流4獲得了更多的資源;低層的流被允許在上層的依賴流完成后立即開始,
作為一個應用程式的開發者,你可以根據你的需要來設定請求中的權重,
例如,你可以在網頁上提供一個縮略圖后,為加載一個高解析度的影像指定一個較低的優先級,
通過提供這種權重分配的便利,HTTP/2使開發者能夠更好地控制網頁渲染,
該協議還允許客戶端在運行時改變依賴關系并重新分配權重,以回應用戶的互動,
然而,需要注意的是,如果某個流被阻止訪問特定資源,服務器可以自行改變分配的優先級,
快取溢位
在兩臺機器之間的任何TCP連接中,客戶端和服務器都有一定量的緩沖空間可用來容納尚未處理的傳入請求,
這些緩沖區為眾多或特別大的請求提供了靈活性,此外,下游和上游連接的速度也不平衡,
然而,在有些情況下,緩沖區是不夠的,
例如,服務器可能以客戶端應用程式無法應付的速度推送大量資料,因為緩沖區大小有限或帶寬較低,
同樣,當客戶端向服務器上傳一張巨大的圖片或視頻時,服務器的緩沖區可能會溢位,導致一些額外的資料包被丟失,
為了避免緩沖區溢位,流量控制機制必須防止發送方用資料淹沒接收方,
本節將概述HTTP/1.1和HTTP/2如何根據其不同的交付模式使用不同版本的該機制來處理流量控制問題,
HTTP/1.1
在HTTP/1.1中,流量控制依賴于基礎的TCP連接,
當該連接啟動時,客戶端和服務器都使用其系統默認設定建立其緩沖區大小,
如果接收方的緩沖區被資料部分填滿,它將告訴發送方其接收視窗,即其緩沖區中剩余的可用空間量,
這個接收視窗在一個被稱為ACK包的信號中公布,ACK包是接收器發送的資料包,以確認它收到了開放信號,
如果這個公告的接收視窗大小為零,發送方將不再發送資料,直到客戶端清除其內部緩沖區,然后請求恢復資料傳輸,
這里需要注意的是,使用基于底層TCP連接的接收視窗,只能在連接的某一端實作流量控制,
因為HTTP/1.1依靠傳輸層來避免緩沖區溢位,每個新的TCP連接都需要一個單獨的流量控制機制,
然而,HTTP/2在一個單一的TCP連接中復用流,將不得不以不同的方式實作流量控制,
HTTP/2
HTTP/2在一個單一的TCP連接中復用資料流,
因此,TCP連接層面的接收視窗不足以調節單個資料流的交付,
HTTP/2通過允許客戶端和服務器實作自己的流量控制,而不是依賴傳輸層來解決這個問題,
應用層傳達可用的緩沖空間,允許客戶端和服務器在復用流的層面上設定接收視窗,
這種細粒度的流控制可以在初始連接后通過WINDOW_UPDATE幀進行修改或維護,
由于這種方法在應用層層面控制資料流,流量控制機制不必等待信號到達其最終目的地后再調整接收視窗,
中介節點可以使用流量控制設定資訊來確定自己的資源分配并進行相應的修改,
通過這種方式,每個中間服務器可以實作自己的自定義資源策略,從而實作更大的連接效率,
在創建適當的資源策略時,流量控制的這種靈活性可能是有利的,
例如,客戶端可以獲取影像的第一次掃描,將其顯示給用戶,并允許用戶預覽,同時獲取更多關鍵資源,
一旦客戶端獲取了這些關鍵資源,瀏覽器將恢復對影像剩余部分的檢索,
因此,將流控制的實作推遲到客戶端和服務器,可以提高網路應用的感知性能,
就流量控制和前一節提到的流優先級而言,HTTP/2提供了一個更詳細的控制水平,為更大的優化提供了可能,
下一節將解釋該協議特有的另一種方法,可以以類似的方式增強連接:用服務器推送預測資源請求,
預測資源請求
在一個典型的網路應用中,客戶端將發送一個GET請求,并收到一個HTML頁面,通常是網站的索引頁,
在檢查索引頁的內容時,客戶端可能會發現它需要獲取額外的資源,如CSS和JavaScript檔案,以便完全呈現該頁面,
客戶端在收到最初的GET請求的回應后才確定它需要這些額外的資源,因此必須發出額外的請求來獲取這些資源并完成頁面的拼接,
這些額外的請求最侄訓增加連接的加載時間,
然而,這個問題是有解決辦法的:由于服務器事先知道客戶端將需要額外的檔案,服務器可以通過在客戶端請求之前將這些資源發送給客戶端來節省時間,
HTTP/1.1和HTTP/2有不同的策略來實作這一點,每一種策略將在下一節描述,
HTTP/1.1——行內資源
在HTTP/1.1中,如果開發者事先知道客戶端機器需要哪些額外的資源來渲染頁面,
他們可以使用一種叫做資源行內的技術,將所需的資源直接包含在服務器回應最初的GET請求而發送的HTML檔案中,
例如,如果客戶端需要一個特定的CSS檔案來渲染頁面,行內該CSS檔案將在客戶端請求之前為其提供所需的資源,從而減少客戶端必須發送的請求總數,
但是,資源行內也有一些問題,
對于較小的、基于文本的資源來說,將資源包含在HTML檔案中是一個可行的解決方案,
但較大的非文本格式的檔案會大大增加HTML檔案的大小,這最侄訓降低連接速度,使使用這種技識訓得的原始優勢化為烏有,
另外,由于行內資源不再與HTML檔案分開,因此沒有機制讓客戶端拒絕它已經擁有的資源,或將資源放入其快取,
如果多個頁面都需要該資源,那么每個新的HTML檔案都會在其代碼中行內相同的資源,從而導致HTML檔案變大,加載時間也比一開始就簡單地快取該資源的情況要長,
那么,資源行內的一個主要缺點是,客戶端不能將資源和檔案分開,需要更精細的控制來優化連接,HTTP/2試圖通過服務器推送來滿足這一需求,
HTTP/2服務端推送
由于HTTP/2能夠對客戶端的初始GET請求做出多個并發回應,服務器可以將資源與請求的HTML頁面一起發送給客戶端,在客戶端要求之前提供資源,
這個程序被稱為服務器推送,
通過這種方式,HTTP/2連接可以實作資源行內的相同目標,同時保持推送資源和檔案之間的分離,
這意味著客戶端可以決定快取或拒絕推送的資源與主要的HTML檔案分開,解決了資源行內的主要缺點,
在HTTP/2中,當服務器發送一個PUSH_PROMISE幀來通知客戶端它要推送一個資源時,這個程序就開始了,
這個框架只包括訊息的標題,并允許客戶端提前知道服務器將推送哪個資源,
如果它已經快取了該資源,客戶端可以通過發送RST_STREAM幀作為回應來拒絕推送,
PUSH_PROMISE幀還可以使客戶端避免向服務器發送重復的請求,因為它知道服務器將推送哪些資源,
這里需要注意的是,服務器推送的重點是客戶端控制,
如果客戶端需要調整服務器推送的優先級,甚至禁用它,它可以在任何時候發送一個SETTINGS幀來修改這個HTTP/2功能,
雖然這個功能有很大的潛力,但服務器推送并不總是優化網路應用的答案,
例如,一些網路瀏覽器不是一直能取消推送的請求,即使客戶端已經有了資源的快取,
如果客戶端錯誤地允許服務器發送重復的資源,服務器推送會不必要地占用連接,
最后,服務器推送的使用應該由開發者決定,
關于如何戰略性地使用服務器推送和優化網路應用的更多資訊,請查看谷歌開發的PRPL模式,
要了解更多關于服務器推送可能出現的問題,請看Jake Archibald的博文HTTP/2推送比我想象的要難,
壓縮
優化網路應用的一個常見方法是使用壓縮演算法來減少客戶端和服務器之間的HTTP訊息的大小,
HTTP/1.1和HTTP/2都使用這種策略,但前者存在實施問題,禁止壓縮整個訊息,
下一節將討論為什么會出現這種情況,以及HTTP/2如何提供解決方案,
HTTP/1.1
像gzip這樣的程式長期以來一直被用來壓縮HTTP訊息中發送的資料,特別是用來減少CSS和JavaScript檔案的大小,
然而,訊息的頭部分總是以純文本形式發送,
雖然每個頭都相當小,但隨著請求的增多,這些未壓縮的資料對連接的負擔越來越重,
特別是對復雜的、需要許多不同資源的API重的網路應用的,因此也就有許多不同的資源請求,
此外,使用cookies有時會使頭檔案變得更大,增加了對某種壓縮的需要,
為了解決這個瓶頸,HTTP/2使用HPACK壓縮來縮小頭檔案的大小,這個話題在下一節進一步討論,
HTTP/2
在HTTP/2中一再出現的主題之一,是它能夠使用二進制框架層來表現出對更細粒度的細節的更大控制,
在涉及到頭的壓縮時也是如此,
HTTP/2可以從其資料中分離出頭,形成一個頭幀和一個資料幀,
然后,HTTP/2特定的壓縮程式HPACK可以壓縮這個頭幀,
這種演算法可以使用Huffman編碼對頭的元資料進行編碼,從而大大減少了其大小,
此外,HPACK可以跟蹤以前傳達的元資料欄位,并根據客戶端和服務器之間共享的動態改變的索引進一步壓縮它們,
例如,以下面兩個請求為例,
method: GET scheme: https host: example.com path: /academy accept: /image/jpeg user-agent: Mozilla/5.0 ...
method: GET scheme: https host: example.com path: /academy/images accept: /image/jpeg user-agent: Mozilla/5.0 ...
這些請求中的各個欄位,如method, scheme, host, accept, user-agent具有相同的值;只有路徑欄位使用不同的值,
因此,當發送第2號請求時,客戶端可以使用HPACK只發送重建這些普通欄位和新編碼路徑欄位所需的索引值,
由此產生的頭幀將如下,
method: GET scheme: https host: example.com path: /academy accept: /image/jpeg user-agent: Mozilla/5.0 ...
path: /academy/images
使用HPACK和其他壓縮方法,HTTP/2又提供了一個可以減少客戶端-服務器延遲的功能,
總結
從這個逐點分析中可以看出,HTTP/2與HTTP/1.1有很多不同之處,
有些功能提供了更高的控制水平,可以用來更好地優化Web應用的性能,而其他功能只是在以前的協議基礎上進行改進,
現在你已經對這兩個協議之間的變化有了一個高層次的看法,你可以考慮HTTP/2中的復用、流優先級、流量控制、服務器推送和壓縮等因素將如何影響網路開發的變化,
如果你想看看HTTP/1.1和HTTP/2之間的性能比較,請看這個Google demo,它對不同延遲的協議進行了比較,
請注意,當你在你的電腦上運行測驗時,頁面加載時間可能會有所不同,這取決于幾個因素,如帶寬、測驗時可用的客戶端和服務器資源,等等,
如果你想研究更詳盡的測驗結果,請看文章《HTTP/2 – A Real-World Performance Test and Analysis》,
最后,如果你想探索如何建立一個現代網路應用程式,你可以跟隨我們的《 How To Build a Modern Web Application to Manage Customer Information with Django and React on Ubuntu 18.04》教程,
或者用我們的《 How To Set Up Nginx with HTTP/2 Support on Ubuntu 16.04》教程建立你自己的HTTP/2服務器,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/396064.html
標籤:其他
