17 排隊也要講效率:HTTP的連接管理

  1. 早期的 HTTP 協議使用短連接,收到響應後就立即關閉連接,效率很低;

在這裏插入圖片描述

  1. HTTP/1.1 默認啓用長連接,在一個連接上收發多個請求響應,提高了傳輸效率;

image

  1. 服務器會發送“Connection: keep-alive”字段表示啓用了長連接;
  2. 報文頭裏如果有“Connection: close”就意味着長連接即將關閉;
  3. 過多的長連接會佔用服務器資源,所以服務器會用一些策略有選擇地關閉長連接;

服務器端通常不會主動關閉連接,但也可以使用一些策略。拿 Nginx 來舉例,它有兩種方式:

  • 使用“keepalive_timeout”指令,設置長連接的超時時間,如果在一段時間內連接上沒有任何數據收發就主動斷開連接,避免空閒連接佔用系統資源。
  • 使用“keepalive_requests”指令,設置長連接上可發送的最大請求次數。比如設置成 1000,那麼當 Nginx 在這個連接上處理了 1000 個請求後,也會主動斷開連接。
  1. “隊頭阻塞”問題會導致性能下降,可以用“併發連接”和“域名分片”技術緩解。

因爲 HTTP 規定報文必須是“一發一收”,這就形成了一個先進先出的“串行”隊列。隊列裏的請求沒有輕重緩急的優先級,只有入隊的先後順序,排在最前面的請求被最優先處理。

如果隊首的請求因爲處理的太慢耽誤了時間,那麼隊列裏後面的所有請求也不得不跟着一起等待,結果就是其他的請求承擔了不應有的時間成本。

image

HTTP 裏就是“併發連接”(concurrentconnections),也就是同時對一個域名發起多個長連接,用數量來解決質量的問題。

但這種方式也存在缺陷。如果每個客戶端都想自己快,建立很多個連接,用戶數×併發數就會是個天文數字。服務器的資源根本就扛不住,或者被服務器認爲是惡意攻擊,反而會造成“拒絕服務”

所以,HTTP 協議建議客戶端使用併發,但不能“濫用”併發。RFC2616 裏明確限制每個客戶端最多併發 2 個連接。不過實踐證明這個數字實在是太小了,衆多瀏覽器都“無視”標準,把這個上限提高到了 6~8。後來修訂的RFC7230 也就“順水推舟”,取消了這個“2”的限制。

域名分片技術,是用數量來解決質量的思路。

HTTP 協議和瀏覽器不是限制併發連接數量嗎?好,那我就多開幾個域名,比如 shard1.chrono.comshard2.chrono.com,而這些域名都指向同一臺服務器 www.chrono.com,這樣實際長連接的數量就又上去了,真是“美滋滋”。不過實在是有點“上有政策,下有對策”的味道。

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