網路連線的基本指標是 latency 和 throughput。用 pipeline 同時提升 latency 和 throughput 還滿直覺的, 但在 http 1.1 上卻意外地以失敗收場, 所以花了點時間查一下為什麼。
What are the disadvantage(s) of using HTTP pipelining? 提到幾個問題:
- http 1.x 是 stateless 的 protocol, client 沒有能力知道 request 之間的 order (沒有流水號)。
- 因此, server 必須依 request order 回傳 response, 但是有些 server 實作錯了。
- 即使 server 作對了, 因為要照 order 回傳 response, server 可能需要暫存大量回應, 有被 DoS 的風險。
- 因為 response 要依順序回傳, client 有 head-of-line blocking 的風險, 比方說剛好先要一個大圖檔再要一個 JS 檔, 結果 JS 檔因此比較慢收到, 讓網頁比較慢取得較重要的檔案。
- client 端的實作比想像中複雜, client 要先偵測 server 是否支援 pipeline 接著才能開始用 pipeline, 因此有些延遲。再者, 因為 client 不會真的只開一個連線, client 還需考慮如何分配 request 到不同連線作 pipeline。
- 因為 http 1.x 過往的限制, 網站早就依 domain 拆開回資料, client 也會同時發多個連線加速。結果是即使 pipeline 都作對了, 可能也沒賺到什麼。
- 此外, server 和 client 中間的 proxy 也可能不支援 (如擔心 DoS) 或是作錯, 又降低了可行的機率。
如果 http 裡面有含流水號, 由 http client library 自己匯合好再依順序回傳資料給上層程式 (像 TCP 那樣), 問題會少一些。設計協定時決定由 server 或 client 處理還挺關鍵的, 一但作錯決定, 協定普及後就很難改了。
HTTP/2 或 SPDY 直接支援 multiplexing, 在一開始就作對了 pipeline。剩下的問題只有使用 TCP 造成 head-of-line blocking (block 的層級不同, 不像 HTTP/1.1 pipeline 那樣嚴重), 但這個得繞過 TCP 才能解決, 也因此 Chrome 又作了 QUIC。QUIC 看來挺有趣的, 不過不像 HTTP2 看來快要普及了 (從 Chrome 6 開始用 SPDY, 這也花了四年以上的時間...)。
Btw, What are the disadvantage(s) of using HTTP pipelining? 附了許多有趣的連結, 有興趣讀讀可以了解更多細節。
沒有留言:
張貼留言