HTTP/1.1隊首阻塞和HTTP/2優化

應用層的優化的方式很多,我知道的有瀏覽器上的優化,通常我們瀏覽一個HTML網頁時,客戶端向服務器端發送請求得到主頁面,主頁面上由很多元素組成,JS文件,CSS樣式文件和各種音頻圖片等資源,等待服務器端發送HTTP或HTTPS響應,在接收到主頁面響應後,開始進行頁面佈局,即構建DOM文檔對象模型。頁面構建完成後,客戶端瀏覽器繼續發送請求,獲取頁面上的子元素(CSS文件,圖片音頻等)進行頁面渲染。由於一個頁面上通常有多個子元素組成,所以客戶端瀏覽器需要發送很多個請求來獲取這些子元素,爲了提高效率,HTTP/1.1版本上使用了一種管道技術來並行發送和處理多個請求。

 

HTTP/1.1管道技術

在HTTP/1.1版本上使用了一種叫Pipelining管道技術的方式,讓客戶端能夠並行發送多個請求,服務器端也可以並行處理多個來自客戶端的請求。在一個TCP連接中,發送多個HTTP請求,不需要等待服務器端對前一個請求的響應之後,再發送下一個請求。但是使用了管道技術的HTTP/1.1,根據HTTP/1.1的規則,服務器端在響應時,要嚴格按照接收請求的順序發送,即先接收到的請求,需要先發送其響應,客戶端瀏覽器也是如此,接收響應的順序要按照自己發送請求的順序來。舉個例子,ajax請求,在客戶端發送多個ajax請求,希望獲得HTML頁面中某一個元素,如果不按照發送請求的順序來接收響應,第一個ajax請求響應時間因爲時間長,而將後面的響應數據覆蓋掉,頁面數據顯示混亂。

 

隊首阻塞問題

總的來說,管道技術允許客戶端和服務器端並行發送多個請求和響應,但是客戶端接收響應的順序要和自己發送請求的順序對應,服務器端發送響應的順序要和自己接收到的請求的順序對應,這樣做似乎沒什麼問題,看起來是不是“FIFO”先來先服務的方式,如果前面收到的一個請求,在服務器端處理的時間很長,生成響應需要很多時間,那麼對於後面的已經處理完生成響應的請求來說,它們只能阻塞等待,等待前面的響應發送完後,自己才能被髮送出去(即使該請求的響應已經生成),造成了“隊首阻塞”問題。可見隊首阻塞發生在服務器端,雖然服務器端並行接收了多個請求,也並行處理生成多個響應,但由於要遵守HTTP/1.1的規則,先接收到的請求需要先發送響應,造成了阻塞問題。

可能你會想到,一個TCP連接上發送請求和接收響應,由於HTTP/1.1的緣故會造成隊首阻塞,那麼一次建立多個TCP連接,不就可以一次下載更多的子元素,更快渲染出HTML頁面。沒錯,建立多個TCP連接的確可以對上面的問題進行優化,但是建立多個TCP連接是十分耗費客戶端和服務器端的資源的,每建立一個連接需要三次握手,1.5次RTT,在連接建立完後,長連接(或者叫連接複用)使得請求和響應完成後,連接不會立刻關閉,即使後面沒有請求發送,服務器也必須維持着這麼一些TCP連接,耗費不少服務器的資源。所以多個TCP連接的優化方式缺陷還是挺大的,最主要是耗費客戶端和服務器端的資源。

      在HTTP/2裏經過更好的改進和設計,解決了HTTP/1.1隊首阻塞問題,其中總結了二進制分幀和並行處理方面,看看HTTP/2做了哪些優化工作。

 

HTTP/2優化

HTTP/2支持在一個TCP連接中並行發送多個請求和接收多個響應,無需等待,因爲對HTTP消息進行二進制分幀的方式進行編碼,客戶端和服務器端之間的消息傳遞變成互不干擾的幀,可以交錯發送,待接收完之後再組裝成完整的消息。由此可見,在HTTP/2上客戶端接收響應無需嚴格按照發送請求的順序,服務器端發送響應也無需嚴格按照接收到請求的順序,只要當前TCP連接可用,雙方就可以互相發送消息。

二進制分幀

       與HTTP/1.1不同,HTTP/2將發送的消息由文本形式轉換成了二進制數據流方式,也就是編碼方式發生了改變。HTTP/2將消息幀編碼成二進制格式,一條消息被拆分成多個幀,幀是最小的通信單位,

每個幀都有編號,這些二進制幀數據流到達另一端後再根據幀的編號進行組裝。幀在客戶端和服務器端的TCP連接上是雙向傳輸的,以字節流的方式,互不干擾(因爲編碼和封裝方式),可以交錯發送,只要當前TCP連接可用,就可以發送請求和響應,消除了HTTP/1.1中請求和響應對應的關係,HTTP/1.1中一個TCP連接要嚴格按照順序發送請求和接收響應,如果一個響應沒有發送出去,那麼後面的響應即使生成完畢,也必須等待。使用了HTTP/2進行通信,二進制分幀的方式使得請求和響應都是以數據流的方式並行發送,客戶端和服務器端接收到數據流後,再根據幀的編號進行組裝,得到完整的消息,以此解決隊首阻塞問題。

並行處理

二進制分幀的方式還有一個好處就是能實現一個TCP連接的請求和響應複用,在一個連接上,客戶端瀏覽器和服務器端可以不斷向對方發送幀,一個請求或響應就是一個數據流,在每個流中交錯發送幀給對方,即實現了並行處理。上面隊首阻塞中的一個問題(或者說優化方案)是建立多個TCP連接來提升並行處理的能力,但是這種方式的缺點很明顯,長連接的方式使得一直保持着多個TCP連接,會耗費客戶端和服務器端的不少資源。在HTTP/2下將消息拆分成多個幀,以二進制編碼交錯發送,當客戶端瀏覽器向服務器端發送數據流(一系列的幀)時,服務器也可以同時發送自己已生成的響應數據流,無需像HTTP/1.1那樣請求與響應匹配,實現了並行發送多個交錯請求和響應,之間互不干擾,並行處理,且只需在一個TCP連接上,減少資源負擔。

到這裏我已經把自己知道的HTTPS性能優化都總結了,上一篇日誌是在網絡層的優化,例如流量控制,啓用慢啓動。應用層優化的地方就很多了,長連接,多個TCP連接,隊首阻塞問題和多個TCP連接耗費資源問題都在HTTP/2裏得到解決,二進制分幀也提供了更好的並行處理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章