第4章:連接管理

  • 作者: 雪山肥魚
  • 時(shí)間:20211109 06:57
  • 目的: 了解http 的連接管理

4.1 TCP 連接(老生常談了)

TCP/IP 全球計(jì)算機(jī)及網(wǎng)絡(luò)設(shè)備都在使用的一種常用分組交換網(wǎng)絡(luò)分層協(xié)議集。意思就是還有其他的比如 ipx/spx 之類的。
收到一個(gè)url:


url與tcp.png

(1) 到(3) 將瀏覽器的ip地址和端口號(hào)從url 分離出來
(4) 建立tcp連接
(5) 發(fā)送請(qǐng)求報(bào)文
(6) 讀取響應(yīng)
(7) 關(guān)閉連接

4.1.1 TCP的可靠數(shù)據(jù)管道

傳輸層: TCP
引用層: HTTP


image.png

注意上述數(shù)據(jù)方向,網(wǎng)絡(luò)傳輸均為大端序。

4.1.2 TCP是分段的,由IP分組傳輸

tcp分段的原因是 IP層的作用。tcp的數(shù)據(jù)是通過名為ip分組的小數(shù)據(jù)塊來發(fā)送的。
HTTP: http over tcp over ip.
HTTPS: 在http 和 tcp 之間插入了 一個(gè) tls/ssl 密碼加密層。


image.png

http 傳送一條報(bào)文,會(huì)以流的形式將報(bào)文數(shù)據(jù)的內(nèi)容通過一條打開的tcp連接按順序傳輸。tcp收到數(shù)據(jù)流之后,會(huì)將數(shù)據(jù)流砍成小塊,并將數(shù)據(jù)封裝在ip分組中。通過internet傳輸。這些工作都是由TCP/IP軟件來處理的,http程序員什么都看不到。


分組.png

最簡(jiǎn)單的包

  1. ip首部
  2. tcp 段首部
  3. tcp數(shù)據(jù)塊

4.1.3 保持tcp連接的正確運(yùn)行

IP可以幫你連接到正確的計(jì)算機(jī),而端口號(hào)則可以將你連接到正確的應(yīng)用程序上去。tcp中 下面2對(duì)標(biāo)定了一個(gè)tcp/ip 連接


image.png

再加上協(xié)議版本,就是五元組。

4.1.4 tcp 套接字編程

api.png

4.2 對(duì)tcp性能的考慮

對(duì)tcp 的性能有所了解

4.2.1 http 事務(wù)的時(shí)延

與建立 tcp 連接,以及傳輸請(qǐng)求和響應(yīng)報(bào)文的時(shí)間相比,事務(wù)處理時(shí)間可能會(huì)很短。
除非客戶端和服務(wù)器超載,或正在處理復(fù)雜的動(dòng)態(tài)資源,否則http時(shí)延就是tcp網(wǎng)絡(luò)時(shí)延構(gòu)成的。

Http 事務(wù)的時(shí)延有以下幾種主要原因

  1. 客戶端首先需要根據(jù)URI 確定 Web 服務(wù)器的IP地址和端口號(hào)。如果最近沒有對(duì)URI中的主機(jī)名進(jìn)行訪問,通過dns解析系統(tǒng)將URI中的主機(jī)名轉(zhuǎn)換成一個(gè)IP地址可能要花費(fèi)數(shù)十秒的時(shí)間。
    http客戶端會(huì)有一個(gè)小的dns緩存,用來保存近期所訪問站點(diǎn)的ip地址。
  2. 發(fā)送tcp連接請(qǐng)求,等待服務(wù)器的請(qǐng)求應(yīng)答。每條新的tcp連接都會(huì)有新的連接建立時(shí)延,時(shí)間大概在1~2s. 但如果有數(shù)百個(gè)http事務(wù)的話,這個(gè)值會(huì)快速的疊加上去。
  3. 網(wǎng)絡(luò)時(shí)延。
  4. 硬件速度、網(wǎng)絡(luò)、服務(wù)器負(fù)載、請(qǐng)求和響應(yīng)報(bào)文的尺寸,以及客戶端和服務(wù)器之間的舉例,tcp協(xié)議的復(fù)雜性等,都會(huì)對(duì)時(shí)延造成巨大影響。

4.2.2 性能聚焦區(qū)域

tcp 相關(guān)時(shí)延:

  1. tcp連接建立握手
  2. tcp 慢啟動(dòng)擁塞控制
  3. 數(shù)據(jù)聚集的 nagle算法
  4. 用于捎帶確認(rèn)的tcp延遲確認(rèn)算法
  5. time_wait 時(shí)延和端口耗盡

4.2.3 tcp 連接的握手時(shí)延

image.png

在發(fā)送數(shù)據(jù)之前,tcp要傳送兩個(gè)分組建立連接
小的http事務(wù)可能會(huì)在tcp建立上花費(fèi)50%,或更多的時(shí)間。

4.2.4 延遲確認(rèn)

因?yàn)镮P層是不可靠的分組傳輸。所以tcp層實(shí)現(xiàn)了自己的確認(rèn)機(jī)制來確保數(shù)據(jù)的成功傳輸。

每個(gè)tcp段都有一個(gè)序列號(hào)和數(shù)據(jù)完整校驗(yàn)和。并且每個(gè)段的接收者收到完好的段時(shí),都會(huì)向發(fā)送者送回小的確認(rèn)分組。如果在指定的窗口時(shí)間內(nèi)收到確認(rèn)信息,發(fā)送者就認(rèn)為分組破壞,則重發(fā)。

因?yàn)榇_認(rèn)分組很小,所以tcp允許在發(fā)往相同方面輸出數(shù)據(jù)分組,捎帶這個(gè)確認(rèn)包。也就是說返回確認(rèn)信息與輸出的數(shù)據(jù)分組結(jié)合在一起。

延遲確認(rèn)算法:

  1. 確認(rèn)包會(huì)在一個(gè)特定的窗口時(shí)間(100ms ~ 200ms)內(nèi),將輸出確認(rèn)放入緩存區(qū)
  2. 尋找能夠捎帶它的輸出分組(和來的時(shí)候同方向)
  3. 200ms后沒有同方向的輸出分組,則單獨(dú)發(fā)送確認(rèn)分組。

但http 的 請(qǐng)求 響應(yīng) 模式,不太希望這種捎帶信息的可能,會(huì)引入大量的時(shí)延,根據(jù)操作系統(tǒng)的不同,和業(yè)務(wù)去修,可以取消延遲確認(rèn)的算法。

4.2.5 tcp 慢啟動(dòng)

tcp連接隨著時(shí)間進(jìn)行自我調(diào)節(jié)。起初會(huì)限制連接的最大速度,如果數(shù)據(jù)傳出,會(huì)慢慢加快。用于防止internet 的突然過載和擁堵。
一開始慢,隨后快的行為也叫做打開擁塞窗口。
所以新的連接肯定會(huì)比老的連接快,所以后續(xù)的上層http可以復(fù)用這些現(xiàn)存的連接工具。

4.2.6 Nagle 算法 與 TCP_NODELAY

tcp 有 一個(gè) 數(shù)據(jù)流接口,可以放任意尺寸在tcp棧中。一次放放一個(gè)字節(jié)也是可以的!但是tcp段中至少裝在了40個(gè)字節(jié)的標(biāo)記和首部,如果tcp 發(fā)送了大量包含少量數(shù)據(jù)的分組,網(wǎng)絡(luò)的性能會(huì)嚴(yán)重下降。
即:窗口綜合癥。

Nagle算法走另一個(gè)極端,鼓勵(lì)全尺寸發(fā)送。只有當(dāng)其他全尺寸分組得到確認(rèn)后,Nagle算法才允許發(fā)送非全尺寸分組。一旦發(fā)出去,數(shù)據(jù)會(huì)被掛起,只有當(dāng)掛起的分組被確認(rèn),才會(huì)發(fā)送其余的緩存數(shù)據(jù)。

Nagle算法也會(huì)引發(fā)幾種http性能問題。

  1. 小的http報(bào)文可能無(wú)法填滿一個(gè)分組。引起時(shí)延
  2. nagle 算法和延遲確認(rèn)之間存在交互問題。
    nagle 算法會(huì)阻止數(shù)據(jù)發(fā)送,直到有確認(rèn)分組到達(dá)為止,但確認(rèn)分組自身會(huì)因?yàn)檠舆t確認(rèn)算法延遲100 - 200 ms。

http應(yīng)用和程序常常會(huì)在自己的棧中設(shè)置參數(shù) tcp_nodelay,金庸Nagle算法。如果這樣組,要確保向tcp寫入大塊數(shù)據(jù)。以免產(chǎn)生窗口綜合征,產(chǎn)生一堆小分組。

4.2.7 TIME_WAIT累積與端口耗盡

tcp端口耗盡歸類于嚴(yán)重的性能問題。
原理:
當(dāng)某個(gè)tcp端點(diǎn)關(guān)閉tcp連接時(shí),會(huì)在內(nèi)存中維護(hù)一個(gè)小的控制塊,用來記錄最近所關(guān)閉連接的ip地址和端口號(hào)。這類信息會(huì)維持一段時(shí)間,是所估計(jì)的最大分段使用期的兩倍,成為2MSL,通常2分鐘。

將2msl值取為2分鐘是有歷史原因的。早期路由器速度慢,將一個(gè)賦值副本丟棄之前,它可以在internet隊(duì)列中保留最多一分鐘,現(xiàn)在生存中期要小的多。

如果msl時(shí)間太短,要小心來組原來socket的分組會(huì)被復(fù)制,然后插入新的tcp流,破壞tcp數(shù)據(jù)。

解決:增加客戶端負(fù)載生成機(jī)器的數(shù)量,也就是增加源端口與源ip的組合。

即使沒有遇到端口耗盡問題,也要特別小心有大量連接處于打開狀態(tài)的情況,或?yàn)樘幱诘却隣顟B(tài)的連接分配了大量控制塊的情況,大量控制塊會(huì)導(dǎo)致有些操作系統(tǒng)速度嚴(yán)重減緩

4.3 http 連接的處理

4.3.1 connection 首部

兩個(gè)相鄰的http應(yīng)用程序會(huì)為他們共享的連接應(yīng)用一組選項(xiàng)。

image.png

  1. 如果連接標(biāo)簽中包含了一個(gè)http首部字段的名稱,那么這個(gè)首部字段就包含了一些和連接有關(guān)的信息。不能將其轉(zhuǎn)發(fā)出去!也就是說,不能轉(zhuǎn)發(fā)到其他節(jié)點(diǎn)。
  2. 將報(bào)文轉(zhuǎn)發(fā)之前,必須刪除connection首部列出的所有首部字段。
  3. http應(yīng)用程序收到 一條帶有connection 首部報(bào)文時(shí),接收端會(huì)解析發(fā)送端請(qǐng)求的所有選項(xiàng),并將其應(yīng)用。將報(bào)文轉(zhuǎn)發(fā)到下一條地址之前,刪除connection 首部以及connection中列出的所有首部

4.3.2 串行事務(wù)處理時(shí)延

image.png

串行時(shí)延高,且用戶體驗(yàn)差

  • 并行連接
    通過多條tcp連接發(fā)起并發(fā)的http請(qǐng)求
  • 持久連接
    重用tcp連接,消除連接及關(guān)閉時(shí)延
  • 管道化連接
    通過共享的tcp連接發(fā)起并發(fā)的http請(qǐng)求
  • 復(fù)用的連接
    交替?zhèn)魉驼?qǐng)求和響應(yīng)報(bào)文

4.4 并行連接

image.png

image.png

頁(yè)面上每個(gè)組件都包含一個(gè)獨(dú)立的http事務(wù)

4.4.1 并行連接可能會(huì)提高頁(yè)面的加載速度

多個(gè)事務(wù)一起來,肯定快的

4.4.2 并行連接并不一定更快

  1. 占帶寬
  2. 打開大量連接會(huì)消耗很多內(nèi)存資源。引發(fā)自身的性能問題。

4.5 持久連接

http/1.1 開始運(yùn)去http設(shè)備在事務(wù)處理結(jié)束之后將tcp連接保持在打開狀態(tài),以便未來的http請(qǐng)求重用現(xiàn)存的連接。
在事務(wù)結(jié)束之后,仍保持在打開狀態(tài)的tcp連接被成為持久連接。

4.5.1 持久以及并行連接

并行連接的缺點(diǎn):

  1. 每個(gè)事務(wù)都會(huì)打開/關(guān)閉 一條新的連接,會(huì)消耗時(shí)間和貸款
  2. 由于tcp慢啟動(dòng)特性的存在,每條新連接的性能都會(huì)有所降低
  3. 可打開的并行連接數(shù)量,實(shí)際是有限的。

持久連接 + 并行連接 是最高效的

4.5.2 http/1.0 + keep-alive 連接

keep-alive 連接 是 早期實(shí)驗(yàn)型持久連接


image.png

實(shí)現(xiàn)http/1.0 keep-alive 連接的客戶端可以通過包含 Connection:Keep-Alive 首部請(qǐng)求,將一條連接保持在打開狀態(tài)。
如果服務(wù)器愿意為下一條請(qǐng)求將連接保持在打開狀態(tài),就在響應(yīng)中包含相同的首部。如果響應(yīng)中沒有connection:keep-alive 首部,客戶端就認(rèn)為服務(wù)器不支持 keep-alive。就會(huì)在發(fā)揮響應(yīng)報(bào)文之后關(guān)閉連接。

4.5.3 keep-alive 連接的限制和規(guī)則

  1. 至少在http/1.0中,keep-alive 并不是默認(rèn)使用的。客戶端必須發(fā)送Connection:keep-alive 請(qǐng)求首部來激活keep-alive連接。
  2. Connection:keep-alive 首部必須隨所希望保持持久連接的報(bào)文一起發(fā)送,客戶端沒有發(fā)送Connection:keep-alive首部,服務(wù)器就會(huì)在那條請(qǐng)求后關(guān)閉連接
  3. 代理和網(wǎng)關(guān)必須執(zhí)行Connection首部規(guī)則。代理或網(wǎng)關(guān)必須在將報(bào)文轉(zhuǎn)發(fā)出去或高速緩存之前,刪除在connection首部中命名的所有首部字段以及Connection 首部自身。
  4. 不應(yīng)該與無(wú)法確認(rèn)是否支持Connection首部的代理服務(wù)器建立keep-alive 連接,以放置出現(xiàn)下面要介紹的呀代理問題。

4.5.4 Keep-Alive 和 啞代理

  • connection首部 和 盲中繼/啞代理
    問題出現(xiàn)代理上,尤其是那些不理解Connection首部,而且不知道沿著轉(zhuǎn)發(fā)鏈路將其發(fā)送之前,應(yīng)該刪掉首部的代理。很多老的或簡(jiǎn)單的代理都是盲中繼,他們只是將字節(jié)從一個(gè)連接轉(zhuǎn)發(fā)到另一個(gè)連接去,不對(duì)connection機(jī)型處理


    盲中繼/啞代理.png

由于中間的啞代理對(duì)keep-alive一無(wú)所知,所以會(huì)將收到的所有數(shù)據(jù)都會(huì)送給客戶端,然后等待源端服務(wù)器關(guān)閉連接。但服務(wù)器認(rèn)為代理已經(jīng)顯示的請(qǐng)求他將連接保持在打開狀態(tài),所以不會(huì)關(guān)閉連接。這樣代理就會(huì)掛在那里等待連接的關(guān)閉。

下一條請(qǐng)求,則忽略,瀏覽器就在這里轉(zhuǎn)圈,無(wú)任何進(jìn)展。

  • 代理和逐跳首部
    避免以上問題,現(xiàn)代的代理都絕不能轉(zhuǎn)發(fā) Connection首部和所有名字出現(xiàn)在connection值中的首部。

4.5.5 插入 Proxy - Connection

針對(duì)啞代理變通做法,不要求所有的web應(yīng)用程序支持高版本的http。名為Proxy-Connection的新首部。
啞代理:Proxy-Connection: 非標(biāo)準(zhǔn)的首部,啞代理轉(zhuǎn)發(fā)后,服務(wù)器會(huì)忽略。則不會(huì)出現(xiàn)任何問題
聰明代理: 用一個(gè)Connection首部取代無(wú)意義的Proxy-Connection首部。

但也只是針對(duì)只有c/s之間一個(gè)代理的問題。而且網(wǎng)絡(luò)中存在很多不可見的代理,如防火墻,攔截緩存等,亦或者是反向代理服務(wù)器的加速器。這種情況仍無(wú)法解決

4.5.6 HTTP/1.1 持久連接

用持久連接(persistent connection)的改進(jìn)設(shè)計(jì)取代。持久連接的目的與keep-alive 相同,但工作機(jī)制更為優(yōu)秀。
默認(rèn)打開 持久連接 應(yīng)用程序必須向報(bào)文中顯示的添加一個(gè)Connection:close 首部. 服務(wù)器收到后 關(guān)閉。

但是C/S之間仍然可以隨時(shí)關(guān)閉空閑連接,不發(fā)送Connection:close并不意味著服務(wù)器承諾永遠(yuǎn)連接保持在打開狀態(tài)
每個(gè)持久連接只適用于一跳傳輸

4.6 管道化連接

在響應(yīng)到達(dá)之前,可以將多條請(qǐng)求放入隊(duì)列。當(dāng)?shù)谝粭l請(qǐng)求通過網(wǎng)絡(luò)流向另一端服務(wù)器時(shí),第二條第三條頁(yè)開始發(fā)送了。
限制:

  1. 非持久連接,則不應(yīng)該使用管道
  2. 必須與請(qǐng)求相同的順序回送http響應(yīng),http報(bào)文中沒有序列號(hào)標(biāo)簽,因此收到響應(yīng)失序了,就無(wú)法與請(qǐng)求匹配了。
  3. 有重發(fā)機(jī)制

4.7 關(guān)閉連接

4.7.1 任意時(shí)刻 接觸連接

http客戶端 服務(wù)器,代理都可以在任意時(shí)刻關(guān)閉一跳tcp傳輸連接。通常會(huì)在一跳報(bào)文結(jié)束時(shí)候關(guān)閉連接,但出錯(cuò)的時(shí)候,也可能在首部行的中間,或其他奇怪的地方關(guān)閉連接。

對(duì)管道化持久連接來說,這種情況是很常見的。http應(yīng)用程序可以在經(jīng)過任意時(shí)間后,關(guān)閉持久連接。

如果服務(wù)器突然關(guān)閉,客戶端就會(huì)在寫入半截請(qǐng)求報(bào)文時(shí)發(fā)現(xiàn)出現(xiàn)了錯(cuò)誤連接。

4.7.2 Content - length 及截尾操作

每條http響應(yīng)都應(yīng)該有精確的Content-length首部,用以描述響應(yīng)主體的尺寸。
客戶端或代理收到一跳隨連接關(guān)閉而結(jié)束的http響應(yīng),且實(shí)際傳輸?shù)膶?shí)體長(zhǎng)度與Content-length并不匹配,則接收端應(yīng)該質(zhì)疑長(zhǎng)度的正確性。
其中中間代理不應(yīng)該糾正Content-length。保證透明性

4.7.3 連接關(guān)閉容限,重試以及冪等

非錯(cuò)誤情況下,連接也可以任意時(shí)刻關(guān)閉。http應(yīng)用程序要做好正確處理非預(yù)期關(guān)閉的準(zhǔn)備。
比如客戶端執(zhí)行事務(wù),傳輸連接關(guān)閉了。那么隊(duì)列里會(huì)出現(xiàn)大量未處理的請(qǐng)求。需要重新調(diào)度。

最明顯的副作用是:
在線訂書,post 一張訂單,突然關(guān)閉連接,客戶端無(wú)法確定服務(wù)端實(shí)際激活了多少事務(wù),get之類的還好,像這種post,可能會(huì)出現(xiàn)重復(fù)執(zhí)行多次的情況,會(huì)有多次下單的危險(xiǎn)。

一個(gè)事務(wù),不管執(zhí)行一次還是多次,結(jié)果是相同的,這個(gè)事務(wù)就叫做冪等的

4.7.4 正常關(guān)閉連接

  1. 完全關(guān)閉與半關(guān)閉
    兩者都調(diào)close 則 全關(guān)閉
    用shutdown單獨(dú)關(guān)閉輸入或輸出信道,成為半關(guān)閉

  2. tcp關(guān)閉及重置錯(cuò)誤
    總之關(guān)閉連接的輸出信道是安全的。玩意還有數(shù)據(jù)進(jìn)來呢?


    image.png

如果另一端向你已經(jīng)關(guān)閉的輸入信道發(fā)送數(shù)據(jù),操作系統(tǒng)就會(huì)向另一端機(jī)器回送一跳tcp "連接被對(duì)端重置"的報(bào)文
大部分操作系統(tǒng)都會(huì)將這種情況作為很嚴(yán)重的錯(cuò)誤處理,刪除對(duì)端還未讀取的所有緩存數(shù)據(jù)(存于客戶端/服務(wù)器)。對(duì)管道化連接是致命的。

比如, 你在一條持久連接發(fā)送了10條管道式請(qǐng)求,響應(yīng)頁(yè)收到了,正在操作系統(tǒng)中緩存(應(yīng)用程序沒有取走)?,F(xiàn)在假設(shè)你發(fā)送了第11條請(qǐng)求,但服務(wù)器認(rèn)為你使用這條連接的時(shí)間已經(jīng)夠長(zhǎng),關(guān)閉了額,那么你的第11條請(qǐng)求會(huì)被發(fā)送到一條已經(jīng)關(guān)閉的連接,并會(huì)向你會(huì)送一條重置信息。這個(gè)重置信息會(huì)清空你的輸入緩沖區(qū)

當(dāng)你試圖讀數(shù)據(jù)的時(shí)候,會(huì)得到一個(gè)連接重置的錯(cuò)誤,數(shù)據(jù)已經(jīng)丟失,景觀其中大部分已經(jīng)成功抵達(dá)過你的機(jī)器了。

  1. 正常關(guān)閉
  2. 先關(guān)閉輸出信道
  3. 兩端都告訴對(duì)方他們不再發(fā)送任何數(shù)據(jù)
  4. 周期性檢查輸入信道的狀態(tài)(查找數(shù)據(jù),或流的末尾)
    一定時(shí)間內(nèi)對(duì)端沒有關(guān)閉輸入信道,則強(qiáng)制關(guān)閉,節(jié)省資源
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 傳輸控制協(xié)議(TCP,Transmission Control Protocol)是一種面向連接的、可靠的、基于字...
    閆鵬飛寫字的地方閱讀 651評(píng)論 0 1
  • TCP連接 TCP/IP是全球計(jì)算機(jī)及網(wǎng)絡(luò)設(shè)備都在使用的一種常用的分組交換網(wǎng)絡(luò)分層協(xié)議集??蛻舳藨?yīng)用程序可以打開一...
    咖啡少年不加糖whm閱讀 625評(píng)論 1 1
  • HTTP 是如何使用TCP連接的 TCP連接的時(shí)延,瓶頸以及存在的故障 HTTP 的優(yōu)化,包括并行連接,keep-...
    minyue閱讀 704評(píng)論 0 0
  • HTTP是如何使用TCP連接的 TCP基礎(chǔ)簡(jiǎn)介 TCP(傳輸控制協(xié)議)(英語(yǔ):Transmission Contr...
    吳晗君閱讀 280評(píng)論 0 0
  • 1. TCP連接 HTTP連接實(shí)際上就是TCP連接和一些使用連接的規(guī)則。TCP連接是因特網(wǎng)上的可靠連接。TCP為H...
    tsyeyuanfeng閱讀 631評(píng)論 0 1

友情鏈接更多精彩內(nèi)容