【網絡通信 -- 直播】IM 學習系列 -- 網絡通信協議簡介(HTTP 協議 四)

【網絡通信 -- 直播】IM 學習系列 -- 網絡通信協議簡介(HTTP 協議 四)

【1】HTTP 的連接管理

【1.1】短連接與長連接

短連接 HTTP 協議最初(0.9/1.0)是個非常簡單的協議,通信過程也採用了簡單的“請求 - 應答”方式;
短連接底層的數據傳輸基於 TCP/IP,每次發送請求前需要先與服務器建立連接,收到響應報文後會立即關閉連接,早期的 HTTP 協議也被稱爲是“無連接”的協議;

短連接的缺點相當嚴重,因爲在 TCP 協議裏,建立連接和關閉連接都是非常“昂貴”的操作,TCP 建立連接要有“三次握手”,發送 3 個數據包,需要 1 個 RTT;關閉連接是“四次揮手”,4 個數據包需要 2 個 RTT,而 HTTP 的一次簡單“請求 - 響應”通常只需要 4 個包,如果不算服務器內部的處理時間,最多是 2 個 RTT,這麼算下來,浪費的時間就是“3÷5=60%”,有三分之二的時間被浪費掉了,傳輸效率低得驚人;

長連接也叫“持久連接”(persistent connections)、“連接保活”(keep alive)、“連接複用”(connection reuse),採用的就是“成本均攤”的思路,既然 TCP 的連接和關閉非常耗時間,那麼就把這個時間成本由原來的一個“請求 - 應答”均攤到多個“請求 - 應答”上,這樣雖然不能改善 TCP 的連接效率,但基於“分母效應”,每個“請求 - 應答”的無效時間就會降低不少,整體傳輸效率也就提高了;

【1.2】連接相關的頭字段

長連接對性能的改善效果非常顯著,在 HTTP/1.1 中的連接都會默認啓用長連接,不需要用什麼特殊的頭字段指定,只要向服務器發送了第一次請求,後續的請求都會重複利用第一次打開的 TCP 連接,在這個連接上收發數據;同時可以在請求頭裏明確地要求使用長連接機制,使用的字段是 Connection,值是“keep-alive”,無論客戶端是否顯式要求長連接,如果服務器支持長連接,總會在響應報文裏放一個“Connection: keep-alive”字段,告訴客戶端“服務器支持長連接,此後便使用該 TCP 一直收發數據”;

服務器端通常不會主動關閉連接,可以使用一些策略;
拿 Nginx 來舉例,它有兩種方式:
1. 使用“keepalive_timeout”指令,設置長連接的超時時間,如果在一段時間內連接上沒有任何數據收發就主動斷開連接,避免空閒連接佔用系統資源;
2. 使用“keepalive_requests”指令,設置長連接上可發送的最大請求次數,比如設置成 1000,那麼當 Nginx 在這個連接上處理了 1000 個請求後,也會主動斷開連接;

【1.3】隊頭阻塞

“隊頭阻塞”與短連接和長連接無關,而是由 HTTP 基本的“請求 - 應答”模型所導致的,因爲 HTTP 規定報文必須是“一發一收”,這就形成了一個先進先出的“串行”隊列,隊列裏的請求沒有輕重緩急的優先級,只有入隊的先後順序,排在最前面的請求被最優先處理,如果隊首的請求因爲處理的太慢耽誤了時間,那麼隊列裏後面的所有請求也不得不跟着一起等待,結果就是其他的請求承擔了不應有的時間成本;

隊頭阻塞性能優化
“併發連接”(concurrent connections)即同時對一個域名發起多個長連接,用數量來解決質量的問題;
“域名分片”(domain sharding)技術,多開幾個域名,這些域名都指向同一臺服務器,這樣實際長連接的數量便增加了;

【2】HTTP 重定向

【2.1】重定向的過程

響應報文中具有“Location”字段,該字段配合 301/302 狀態碼纔有意義,該字段標記了服務器要求重定向的 URI;瀏覽器收到 301/302 報文,會檢查響應頭裏有沒有“Location”字段,如果有,就從字段值裏提取出 URI,發出新的 HTTP 請求,在“Location”裏的 URI 既可以使用絕對 URI,也可以使用相對 URI;所謂“絕對 URI”,就是完整形式的 URI,包括 scheme、host:port、path 等,所謂“相對 URI”,就是省略了 scheme 和 host:port,只有 path 和 query 部分,是不完整的,但可以從請求上下文裏計算得到;注意,在重定向時如果只是在站內跳轉,可以放心地使用相對 URI,但如果要跳轉到站外,就必須用絕對 URI;

【2.2】重定向狀態碼

301 即“永久重定向”(Moved Permanently),即原 URI 已經“永久”性地不存在了,今後的所有請求都必須改用新的 URI;瀏覽器看到 301,就知道原來的 URI“過時”了,就會做適當的優化;
302 即“臨時重定向”(“Moved Temporarily”),即原 URI 處於“臨時維護”狀態,新的 URI 是起“頂包”作用的“臨時工”,瀏覽器或者爬蟲看到 302,會認爲原來的 URI 仍然有效,但暫時不可用,所以只會執行簡單的跳轉頁面,不記錄新的 URI,也不會有其他的多餘動作,下次訪問還是用原 URI;
303 See Other,類似 302,但要求重定向後的請求改爲 GET 方法,訪問一個結果頁面,避免 POST/PUT 重複操作;
307 Temporary Redirect,類似 302,但重定向後請求裏的方法和實體不允許變動,含義比 302 更明確;
308 Permanent Redirect,類似 307,不允許重定向後的請求變動,但具有 301“永久重定向”的含義;

【2.3】重定向的應用場景

1. “資源不可用”需要用另一個新的 URI 來代替;
2. “避免重複”讓多個網址都跳轉到一個 URI,增加訪問入口的同時還不會增加額外的工作量;

【2.4】重定向的相關問題

1. “性能損耗”,重定向的機制決定了一個跳轉會有兩次請求 - 應答,比正常的訪問多了一次;
2. “循環跳轉”,若重定向的策略設置欠考慮,可能會出現“A=>B=>C=>A”的無限循環,不停地在這個鏈路裏循環;

參考致謝
本博客爲博主的學習實踐總結,並參考了衆多博主的博文,在此表示感謝,博主若有不足之處,請批評指正。

【1】透視HTTP協議

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