HTTP總結

WeiZhao_111發表於2018-07-01

HTTP/1.1 時代

HTTP/1.1 對 HTTP/1.0 做了許多優化,也是當今使用得最多的 HTTP 協議:

  1. 持久化連線以支援連線重用
  2. 分塊傳輸編碼以支援流式響應
  3. 請求管道以支援並行請求處理
  4. 位元組服務以支援基於範圍的資源請求
  5. 改進的更好的快取機制

持久連線

在 HTTP/1.0 時代,每一個請求都會重新建立一個 TCP 連線,一旦響應返回,就關閉連線。 而建立一個連線,則需要進行三次握手(https的話則是9次握手),這極大的浪費了效能

img

因此 HTTP/1.1 新增了「keep-alive」功能,當瀏覽器建立一個 TCP 連線時,多個請求都會使用這條連線。(現如今大多數瀏覽器預設都是開啟的)

img

PipeLining 管道

持久連線解決了連線複用問題,但還是存在著一個問題:在一個 TCP 連線中,同一時間只能夠傳送一個請求,並且需要等響應完成才能夠傳送第二個請求。

因此 HTTP/1.1 制訂了 PipeLining 管道,通過這個管道,瀏覽器的多個請求可以同時發到伺服器,但是伺服器的響應只能夠一個接著一個的返回 ( 但各大瀏覽器有些不支援/預設關閉,因此這功能可以說是雞肋)

img

因為每一條連線同時只能夠返回一個響應,因此瀏覽器為了改善這種情況,會同時開啟4~8個 TCP 連線進行傳送請求。

小結

在 HTTP/1.1 時代主要增加了:

  1. keep-alive 選項,建立連線後,在一定時間內不會斷開,其他請求都可以使用這條連線。
  2. pipelining 管道,通過這個管道,瀏覽器的多個請求可以同時發到伺服器,但是伺服器的響應只能夠一個接著一個的返回 ( 但各大瀏覽器有些不支援/預設關閉,因此這功能可以說是雞肋)

HTTP/1.1 時代的優化

1、連線和拼接

連線或拼接JS和CSS檔案,雪碧圖,以減少HTTP請求,同時瀏覽器可快取這些靜態資源,為下次訪問節約時間。但是這樣帶來的副作用是,維護成本高,其中某一個小改動都會使得整個拼接後的檔案發生改變,重新快取。

當然並不是說無止境的拼接,建議大小為: 30~50 KB

2、域名分割槽

由於瀏覽器的限制,同一個域名下最多隻能建立6個連線(不同的瀏覽器限制不一樣)。我們通常使用子域名來減少所有資源在只有一個連線時的產生的排隊延遲。這個顯然不適用在HTTP2中,因為不同的域需要建立不同的連線。

3、資源內嵌

對於不常用的,較小大資源內嵌在文件中,比如base64的圖片,以減少HTTP請求,但是這樣的資源不能在瀏覽器中快取,也不可能被其他頁面共享,同時還有可能編碼之後的資源變等更大了。在HTTP2中,這樣的資源就可以使用SERVER PUSH來推送。

建議:

  1. 只考慮嵌入1~2 KB 以下的資源,因為小於這個標準的資源經常會導致比它自身更高的HTTP 開銷
  2. 如果檔案很小,而且只有個別頁面使用,可以考慮嵌入。理想情況下,最好是隻用一次的資源
  3. 如果檔案很小,但需要在多個頁面中重用,應該考慮集中打包
  4. 如果小檔案經常需要更新,就不要嵌入了
  5. 通過減少 HTTP cookie的大小將協議開銷最小化

SPDY 時代

由於現代網頁的不斷豐富, HTTP/1.1 協議的效能也逐漸吃不消,因此2012年google(google就是牛逼)如一聲驚雷提出了SPDY的方案,實際上,HTTP/2.0 也是以 SPDY 作為原型進行開發的。

SPDY基礎功能

多路複用(multiplexing)

多路複用通過多個請求stream共享一個tcp連線的方式,解決了http1.x holb(head of line blocking)的問題,降低了延遲同時提高了頻寬的利用率。

請求優先順序(request prioritization)

多路複用帶來一個新的問題是,在連線共享的基礎之上有可能會導致關鍵請求被阻塞。SPDY允許給每個request設定優先順序,這樣重要的請求就會優先得到響應。比如瀏覽器載入首頁,首頁的html內容應該優先展示,之後才是各種靜態資原始檔,指令碼檔案等載入,這樣可以保證使用者能第一時間看到網頁內容。

header壓縮

前面提到過幾次http1.x的header很多時候都是重複多餘的。選擇合適的壓縮演算法可以減小包的大小和數量。SPDY對header的壓縮率可以達到80%以上,低頻寬環境下效果很大。

SPDY 現已經被大多數瀏覽器以及 WEB 伺服器所支援,但為了推進 HTTP/2.0, Google 已經宣佈在 2016年對其停止開發。

HTTP/2.0 時代

2015年5月, HTTP/2.0 在萬眾矚目下以RFC 7540正式發表。(熱烈鼓掌~啪啪啪啪~~)

二進位制分幀

在應用層與傳輸層之間增加一個二進位制分幀層,以此達到“在不改動HTTP的語義,HTTP 方法、狀態碼、URI及首部欄位的情況下,突破HTTP1.1的效能限制,改進傳輸效能,實現低延遲和高吞吐量。”

在二進位制分幀層上,HTTP2.0會將所有傳輸的資訊分割為更小的訊息和幀,並對它們採用二進位制格式的編碼,其中HTTP1.x的首部資訊會被封裝到Headers幀,而我們的request body則封裝到Data幀裡面。

img

壓縮頭部

HTTP/2.0規定了在客戶端和伺服器端會使用並且維護「首部表」來跟蹤和儲存之前傳送的鍵值對,對於相同的頭部,不必再通過請求傳送,只需傳送一次

事實上,如果請求中不包含首部(例如對同一資源的輪詢請求),那麼首部開銷就是零位元組。此時所有首部都自動使用之前請求傳送的首部。

如果首部發生變化了,那麼只需要傳送變化了資料在Headers幀裡面,新增或修改的首部幀會被追加到“首部表”。首部表在 HTTP2.0的連線存續期內始終存在,由客戶端和伺服器共同漸進地更新。

img

多路複用

HTTP/2.0 時代擁有了「多路複用」功能,意思是: 在一條連線上,我可以同時發起無數個請求,並且響應可以同時返回。

這個連線可以承載任意數量的雙向資料流。在過去, HTTP 效能優化的關鍵並不在於高頻寬,而是低延遲。TCP 連線會隨著時間進行自我調節,起初會限制連線的最大速度,如果資料成功傳輸,會隨著時間的推移提高傳輸的速度。這種調節則被稱為 TCP 慢啟動。由於這種原因,讓原本就具有突發性和短時性的 HTTP 連線變的十分低效。HTTP/2.0 通過讓所有資料流共用同一個連線,可以更有效地使用 TCP 連線,讓高頻寬也能真正的服務於 HTTP 的效能提升。

這種單連線多資源的方式,減少服務端的連線壓力,記憶體佔用更少,連線吞吐量更大;而且由於 TCP 連線的減少而使網路擁塞狀況得以改善,同時慢啟動時間的減少,使擁塞和丟包恢復速度更快。

img

客戶端和伺服器可以把HTTP訊息分解為互不依賴的幀,然後亂序傳送,最後再在另一端把它們重新組合起來。注意,同一連結上有多個不同方向的資料流在傳輸。客戶端可以一邊亂序傳送stream,也可以一邊接收者伺服器的響應,而伺服器那端同理。

img

也就是說,HTTP2.0通訊都在一個連線上完成,這個連線可以承載任意數量的雙向資料流。就好比,我請求一個頁面www.qq.com%E3%80%82%E9%A1%B5%E9%9D%A2%E4%B8%8A%E6%89%80%E6%9C%89%E7%9A%84%E8%B5%84%E6%BA%90%E8%AF%B7%E6%B1%82%E9%83%BD%E6%98%AF%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%B8%8E%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84%E4%B8%80%E6%9D%A1TCP%E4%B8%8A%E8%AF%B7%E6%B1%82%E5%92%8C%E5%93%8D%E5%BA%94%E7%9A%84%EF%BC%81

注意,對一個域名,只需要開啟一條 TCP 連線,請求都在這條 TCP 連線上幹活。

因此在 HTTP/2.0 時代,之前的合併 JS、CSS 檔案技巧,反而不適用了。

請求優先順序

既然所有資源都是並行傳送,那麼就需要「優先順序」的概念了,這樣就可以對重要的檔案進行先傳輸,加速頁面的渲染。

伺服器推送

在 HTTP2.0中,伺服器推送是指在客戶端請求之前傳送資料的機制。如果一個請求是由你的主頁發起的,伺服器很可能響應主頁內容、logo以及樣式表,因為它知道客戶端會用到這些東西。這相當於在一個 HTML 文件內集合了所有的資源,不過與之相比,伺服器推送有一個很大的優勢:可以快取!

強制 SSL

雖然 HTTP/2.0 協議並沒宣告一定要用 SSL,但是 Google Chrome 等瀏覽器強制要求使用 HTTP/2.0 必須要用上 SSL, 也就是說必須要: https://

http:// 將繼續使用 http/1.0

對優化的影響:

  1. 因為“所有的HTTP2.0的請求都在一個TCP連結上”,“資源合併減少請求”,比如CSS Sprites,多個JS檔案、CSS檔案合併等手段沒有效果,或者說沒有必要。

  2. 因為“多路複用”,採用“cdn1.cn,cdn2.cn,cdn3.cn,開啟多個TCP會話,突破瀏覽器對同一域名的連結數的限制”的手段是沒有必要的。因為因為資源都是並行交錯傳送,且沒有限制,不需要額外的多域名並行下載。

  3. 因為“伺服器推送”,內嵌資源的優化手段也變得沒有意義了。而且使用伺服器推送的資源的方式更加高效,因為客戶端還可以快取起來,甚至可以由不同的頁面共享(依舊遵循同源策略)

如何使用上 HTTP/2.0

1. 需要瀏覽器的支援,目前最新版的 Chrome、Opera、 FireFox、 IE11、 edge 都已經支援了
2. 需要 WEB 伺服器的支援,比如 Nginx , H20
複製程式碼

如果瀏覽器或伺服器有一方不支援,那麼會自動變成 Http/1.1

HTTP/1.1 HTTP/2.0效能比較

https://http2.akamai.com/demo 這是Akamai公司建立的一個官方演示,這個演示同時請求379張圖片,用於展示HTTP/1.1和HTTP/2的效能差距。不同的電腦配置、網路情況以及伺服器負載等情況不同,得到的結果肯定也不同,下圖是使用自己的電腦載入時間截圖:

HTTP總結

參考:

HTTP/2.0 簡單總結

面試時如何優雅的談論HTTP/1.0/1.1/2.0

服務化基石之遠端通訊系列二:通訊協議之應用層

相關文章