HTTP HTTP 1.X 1. HTTP是建立在TCP協議上的,HTTP協議的瓶頸及優化都是基於TCP協議本身的特性。 2. TCP建立連接時有三次握手 會有1.5RTT的延遲,為了避免每次請求都經歷握手待來的延遲,應用層會選擇不同策略的http長連接。 HTTP 1.0 連接不能復用以及有hea ...
HTTP
HTTP 1.X
HTTP是建立在TCP協議上的,HTTP協議的瓶頸及優化都是基於TCP協議本身的特性。
TCP建立連接時有三次握手 會有1.5RTT的延遲,為了避免每次請求都經歷握手待來的延遲,應用層會選擇不同策略的http長連接。
HTTP 1.0 連接不能復用以及有head of line blocking問題。
http1.0協議頭裡可以設置Connection:Keep-Alive。在header里設置Keep-Alive可以在一定時間內復用連接,具體復用時間的長短可以由伺服器控制,一般在15s左右。到http1.1之後Connection的預設值就是Keep-Alive,如果要關閉連接復用需要顯式的設置Connection:Close。
<br />
head of line blocking會因為一個request沒有到達伺服器或者一個response因為網路沒有及時返回而影響後續所有請求。
連接復用問題
tcp長鏈接
http long-polling
客戶端在初始狀態會發送一個polling請求到伺服器,伺服器並不會馬上返回業務數據,而是等待有新的業務數據產生時返回。所以連接會被保持,一旦結束馬上又會發起一個新的polling請求,反覆如此。
http streaming
與long-polling不同,server並不會結束初始的streaming請求,而是持續的通過這個通道返回最新的業務數據,但這個通道時單向的。
web socket
與傳統的 tcp socket連接相似,也是基於tcp協議,並提供雙向的數據通道。
解決head of line blocking
http pipelining
讓每個請求不用等待其他請求的response返回之後才發出,而是幾乎在同一時間把request發送給伺服器。
SPDY
http 1.X存在諸多問題,在嘗試了各種優化手段後提出的SPDY方案。
SPDY目標
- 降低延遲,客戶端的單連接單請求,server的FIFO響應隊列都是延遲的大頭。
- http最初設計都是客戶端發起請求,然後server響應,server無法主動push內容到客戶端。
- 壓縮http header,http1.x的header越來越膨脹,cookie和user agent很容易讓header的size增至1kb大小,甚至更多。而且由於http的無狀態特性,header必須每次request都重覆攜帶,很浪費流量。
SPDY基礎功能
- 多路復用。多路復用通過多個請求stream共用一個tcp連接的方式,解決了http 1.x hold of line blocking 的問題,降低了延遲同時提高了帶寬的利用率。
- 請求優先順序。多路復用帶來一個新的問題,在連接共用的基礎上可能導致一些關鍵請求被阻塞。
- header壓縮。 http1.X的 header很多時候都是重覆多餘的。選擇合適的壓縮演算法可以減小包的大小和數量。
SPDY高級功能
- server推送。 http1.x只能由客戶端發起請求,然後伺服器被動的發送response。開啟server push之後,server通過
X-Associated-Content header
告知客戶端會有新的內容推送過來。 - server暗示。 和server push不同的是,server hint並不會主動推送內容,只是告訴有新的內容產生,內容的下載還是需要客戶端主動發起請求。server hint通過
X-Subresources header
來通知。
HTTP 2.0
- 客戶端向server發送request這種基本模式不會變。
- 老的scheme不會變,使用
http://和https://
的服務和應用不會要做任何更改。 - 使用http1.x的客戶端和伺服器可以無縫的通過代理方式轉接到http2.0 上
- 不識別http2.0的代理伺服器可以將請求降級到http1.x
HTTP 2.0主要改動
新的二進位格式
http 1.x是明文協議,格式由strat line
,header
,body
組成。需要做協議解析來識別這3哥部分,http1.x的解析是基於文本的,而文本格式解析存在天然缺陷,二進位比文本格式更方便且健壯。
http 2.0的格式定義更接近tcp。由Length
,Type
,Flags
,Stream ID
,Payload
5個部分組成。
length
定義了整個frame的開始到結束type
定義frame的類型flags
用bit位定義了一些重要的參數stream id
用作流控制payload
就是request的正文
連接共用
stream id
作用就是連接共用機制,一個request對應一個stream並分配一個id,這樣一個連接上可以有多個stream,每個stream的frame隨機混雜在一起,接收方根據stream id將frame再歸屬到各自不同的request裡面。每個stream都可以設置優先順序和依賴。
header壓縮
http2.0使用encoder來減少需要傳輸的header大小,通訊雙方各自cache一份header fields表,避免重覆header傳輸,減少傳輸大小。
壓縮演算法選擇
SPDY/2使用的是gzip 壓縮演算法,後來出現BREACH
和CRIME
2種攻擊方式,即使走SSL的SPDY也可以破解內容,http2.0採用HPACK
的壓縮演算法。
重置連接表現
對於http 1.x來說,是通過設置tcp segment里的reset flag來通知對端關閉連接。http2.0引入RST_STREAM
類型的frame,可以在不斷開連接的前提下取消某個request的stream。
流量控制
http2.0 通過類似receive window
的做法,數據的接收方通過告知對方自己的flow window
大小表明自己還能接收多少數據。只有Data類型的 frame才有流量控制功能。
服務推送
http2.0 通過push的方式將客戶端需求的內容預先推送過去,也叫cache push
。如果客戶端退出,需取消server push
,可以通過發送RST_STREAM
類型的frame來做到。
Nagle Algorithm/TCP Delayed Ack
Nagle Algorithm/TCP Delayed Ack
是一組對立的演算法。http2.0可以通過TCP_NODELAY
禁用Nagle或TCP_QUICKACK
禁用ACK。官方推薦設置TCP_NODELAY
更安全的SSL
HTTP2.0使用了tls的拓展ALPN來做協議升級,除此之外加密這塊還有一個改動,HTTP2.0對tls的安全性做了近一步加強