http/1中的每個請求都會建立一個單獨的連接,除了在每次建立連接過程中的三次握手之外,還存在TCP的慢啟動導致的傳輸速度低。其實大部分的http請求傳送的數據都很小,就導致每一次請求基本上都沒有達到正常的傳輸速度。
在http1.1中默認開啟keep-alive,解決了上面說到的問題,但是http的傳輸形式是一問一答的形式,一個請求對應一個響應(http2中已經不成立,一個請求可以有多個響應,server push),在keep-alive中,必須等下上一個請求接受才能發起下一個請求,所以會收到前面請求的阻塞。
使用pipe-line可以連續發送一組沒有相互依賴的請求而不比等到上一個請求先結束,看似pipe-line是個好東西,但是到目前為止我還沒見過這種類型的連接,也間接說明這東西比較雞肋。pipe-line依然沒有解決阻塞的問題,因為請求響應的順序必須和請求發送的順序一致,如果中間有某個響應花了很長的時間,后面的響應就算已經完成了也要排隊等阻塞的請求返回,這就是線頭阻塞。
http2的多路復用就很好的解決了上面所提出的問題。http2的傳輸是基於二進制幀的。每一個TCP連接中承載了多個雙向流通的流,每一個流都有一個獨一無二的標識和優先級,而流就是由二進制幀組成的。二進制幀的頭部信息會標識自己屬於哪一個流,所以這些幀是可以交錯傳輸,然后在接收端通過幀頭的信息組裝成完整的數據。這樣就解決了線頭阻塞的問題,同時也提高了網絡速度的利用率。