http學習 http的連線管理

2022-09-20 18:06:10 字數 2983 閱讀 3035

http 協議最初(0.9/1.0)是個非常簡單的協議,通訊過程也採用了簡單的「請求 - 應答」方式。

它底層的資料傳輸基於 tcp/ip,每次傳送請求前需要先與伺服器建立連線,收到響應報文後會立即關閉連線。因為客戶端與伺服器的整個連線過程很短暫,不會與伺服器保持長時間的連線狀態,所以就被稱為「短連線」(short-lived connections)。

早期的 http 協議也被稱為是「無連線」的協議。短連線的缺點相當嚴重,因為在 tcp 協議裡,建立連線和關閉連線都是非常「昂貴」的操作。

tcp 建立連線要有「三次握手」,傳送 3 個資料報,需要 1 個 rtt;關閉連線是「四次揮手」,4 個資料報需要 2 個 rtt。而 http 的一次簡單「請求 - 響應」通常只需要 4 個包,如果不算伺服器內部的處理時間,最多是 2 個 rtt。這麼算下來,浪費的時間就是「3÷5=60%」,有三分之二的時間被浪費掉了,傳輸效率低得驚人。

很顯然,短連線的缺點嚴重制約了伺服器的服務能力,導致它無法處理更多的請求。

ps:乙個來回就是1rtt,三次**準確來說是1.5個rtt,四次揮手是兩個來回,所以是2rtt。

針對短連線暴露出的缺點,http 協議就提出了「長連線」的通訊方式,也叫「持久連線」(persistent connections)、「連線保活」(keep alive)、「連線復用」(connection reuse)。

其實解決辦法也很簡單,用的就是「成本均攤」的思路,既然 tcp 的連線和關閉非常耗時間,那麼就把這個時間成本由原來的乙個「請求 - 應答」均攤到多個「請求 - 應答」上。

這樣雖然不能改善 tcp 的連線效率,但基於「分母效應」,每個「請求 - 應答」的無效時間就會降低不少,整體傳輸效率也就提高了。

下圖是短連線與長連線的對比示意圖。

由於長連線對效能的改善效果非常顯著,所以在http/1.1 中的連線都會預設啟用長連線。

不需要用什麼特殊的頭字段指定,只要向伺服器傳送了第一次請求,後續的請求都會重複利用第一次開啟的 tcp 連線,也就是長連線,在這個連線上收發資料。

當然,我們也可以在請求頭里明確地要求使用長連線機制,使用的字段是 connection,值是「keep-alive」。

不過不管客戶端是否顯式要求長連線,如果伺服器支援長連線,它總會在響應報文裡放乙個「connection: keep-alive」字段,告訴客戶端:「我是支援長連線的,接下來就用這個 tcp 一直收發資料吧」。

因為 tcp 連線長時間不關閉,伺服器必須在記憶體裡儲存它的狀態,這就占用了伺服器的資源。如果有大量的空閒長連線只連不發,就會很快耗盡伺服器的資源,導致伺服器無法為真正有需要的使用者提供服務。

所以,長連線也需要在恰當的時間關閉,不能永遠保持與伺服器的連線,這在客戶端或者伺服器都可以做到。

在客戶端,可以在請求頭里加上「connection: close」字段,告訴伺服器:「這次通訊後就關閉連線」。伺服器看到這個字段,就知道客戶端要主動關閉連線,於是在響應報文裡也加上這個字段,傳送之後就呼叫 socket api 關閉 tcp 連線。

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

另外,客戶端和伺服器都可以在報文裡附加通用頭欄位「keep-alive: timeout=value」,限定長連線的超時時間。但這個欄位的約束力並不強,通訊的雙方可能並不會遵守,所以不太常見。

「隊頭阻塞」

head-of-line blocking,也叫「隊首阻塞」

「隊頭阻塞」與短連線和長連線無關,而是由 http 基本的「請求 - 應答」模型所導致的。

因為 http 規定報文必須是「一發一收」,這就形成了乙個先進先出的「序列」佇列。佇列裡的請求沒有輕重緩急的優先順序,只有入隊的先後順序,排在最前面的請求被最優先處理。

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

效能優化

「同時對乙個網域名稱發起多個長連線,用數量來解決質量的問題。」http 允許客戶端使用併發,但不能濫用。

http 協議和瀏覽器不是限制併發連線數量嗎?好,那我就多開幾個網域名稱,比如 shard1.chrono.com、shard2.chrono.com,而這些網域名稱都指向同一臺伺服器 www.chrono.com。

1、在開發基於 http 協議的客戶端時應該如何選擇使用的連線模式呢?短連線還是長連線?

2、應當如何降低長連線對伺服器的負面影響呢?

答:使用一定的保護措施,比如:按超時時間或請求次數來關閉連線,也可以搞乙個連線池來防護伺服器。

1、隊頭阻塞在http和tcp層次都有,原因不同。

對於tcp隊頭阻塞:每個 tcp 分組都會帶著乙個唯一的序列號被發出,而所有分組必須按順序傳送到接收端。如果中途有乙個分組沒能到達接收端,那麼後續分組必須儲存到接收端的 tcp 緩衝區,等待丟失的分組重發並到達接收端。這一切都發生在 tcp 層,應用程式對 tcp 重發和緩衝區中排隊的分組一無所知,必須等待分組全部到達才能訪問資料。在此之前,應用程式只能在通過套接字讀資料時感覺到延遲互動。這種效應稱為 tcp 的隊首阻塞。

2、rtt(round-trip time): 往返時延。

在計算機網路中它是乙個重要的效能指標,表示從傳送端傳送資料開始,到傳送端收到來自接收端的確認(接收端收到資料後便立即傳送確認),總共經歷的時延。

一般認為單向時延=傳輸時延t1+傳播時延t2+排隊時延t3

t1是資料從進入節點到傳輸**所需要的時間,通常等於資料塊長度/通道頻寬

t2是訊號在通道中需要傳播一定距離而花費的時間,等於通道長度/傳播速率(光纖中電磁波的傳播速率約為2*10^5 km/s,銅纜中2.3*10^5 km/s)

t3可籠統歸納為隨機雜訊,由途徑的每一跳裝置及收發兩端負荷情況及吞吐排隊情況決定(包含網際網路裝置和傳輸裝置時延)

HTTP連線管理

http通訊是由tcp ip承載的,tcp ip是全球計算機及網路裝置都在使用的一種常用的分組交換網路分層協議集。http連線實際上就是tcp連線和一些使用連線的規則。tcp的資料是通過名為ip分組 或ip資料報 的小資料塊來傳送的。http要傳送一條報文時,會以流的形式將報文資料的內容通過一條開啟...

http協議學習 連線管理

出自 4.1 tcp連線 tcp為http提供了一條可靠的位元傳輸管道,按順序正確的傳輸,步驟如下 瀏覽器解析主機名。查詢這個主機名的ip位址 dns 獲得埠號。瀏覽器對伺服器該埠號發起連線。向伺服器傳送請求報文。從伺服器獲取響應報文。連線關閉。4.1.2 tcp流是分段的 由ip分組傳送 tcp的...

日常 HTTP連線管理

http連線管理 1.誤解的connection首部 當http報文經過中間客戶端到服務端中間的各種 裝置時,對標籤中列出的頭資訊進行刪除,close是事務結束後關掉此條連線 2.消除序列化的時延 並行連線 多條tcp連線發起併發的http請求 持久連線 重用tcp連線,消除連線和關閉時延 管道化連...