回覆列表
  • 1 # 遷徙de麻雀

    這個需要分協議版本解釋。

    HTTP1.0/0.9

    http1.0不支援keep-alive,要完成一次HTTP請求,需要建立一個新的TCP連線,然後傳送http請求,待接收響應後關閉連線。

    HTTP1.1

    http1.1預設使用keep-alive,一次HTTP請求完成後不會關閉TCP連線,會繼續為下一個HTTP請求服務(可以類比資料庫連線池和執行緒池的設計),減小建立和關閉TCP連線的開銷(三次握手四次揮手)。

    比較大的入口網站,比如京東,首頁請求非常多,但是大量都需要排隊等TCP空閒。這樣設計的出發點主要是效能,否則會佔用伺服器太多Socket資源(考慮socket預留的讀寫緩衝區,windows的核心物件或者linux的檔案控制代碼)或者變相地造成DoS攻擊。

    從這個角度看,TCP通道在傳輸的時候,同一時間只對應一次HTTP請求,同時在它關閉之前可能會傳輸很多次不同的HTTP請求。所以,HTTP頭部的Content-Length非常重要,這樣才能從TCP流中根據長度提取一個完整HTTP訊息。

    Pipelineing模式一般都不用,這裡直接無視過掉。

    異常

    如果因為網路原因導致TCP連線失效,結果會怎麼樣?

    標準的HTTP協議實現元件,只會給上層完整的HTTP訊息處理。舉個例子,Web伺服器接受客戶端Put或者Post的大檔案(比如800M),伺服器的HTTP協議層會使用臨時檔案儲存接收,完整接收整個訊息後,再透過臨時檔案流的方式交給應用服務處理。

    如果檔案尚未傳輸完畢,TCP連線失效的話,前面所有的傳輸都浪費了。必須重新發起。

    所以,HTTP協議傳輸檔案需要自己做分片,就是這個道理。

    使用Tips

    HTTP客戶端元件一般會提供諸如ConnectionLimit的選項讓你控制最大TCP連線數。如果你是桌面客戶端,或者請求遠端服務,不宜設定過大。如果你是內部服務之間呼叫,可以根據需求合理設定以增加併發效能。

    Web服務端一般會提供限制請求訊息大小的選項,如果你需要傳輸大檔案,特別注意這個選項。

    還有到底在記憶體中還是臨時檔案中儲存客戶端上傳的檔案的閥值,如果你記憶體夠用,可以考慮稍微設定大一點,比如上傳圖片較多,可以考慮設定5M左右,避免磁碟延遲。

  • 中秋節和大豐收的關聯?
  • 花生瘡痂病是用己唑醇好,還是用戊唑醇好?為什麼?