偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

圖解 HTTP 連接管理

網(wǎng)絡(luò) 通信技術(shù)
所有 HTTP 客戶端、服務(wù)器或者代理都可以在任意時(shí)刻關(guān)閉一條 HTTP 傳輸連接。通常情況下會(huì)在一次響應(yīng)后關(guān)閉連接,但是保不準(zhǔn)也會(huì)在 HTTP 事務(wù)的過(guò)程中出現(xiàn)。

[[414965]]

Hey guys ,這里是程序員cxuan,歡迎你收看我最新一期的文章。

熟悉我的小伙伴都知道,我之前肝了本《HTTP 核心總結(jié)》的 PDF,這本 PDF 是取自我 HTTP 系列文章的匯總,然而我寫的 HTTP 相關(guān)內(nèi)容都是一年前了,我回頭看了一下這本 PDF,雖然內(nèi)容不少,但是很多內(nèi)容缺少系統(tǒng)性,看起來(lái)不爽,這個(gè)有悖于我的初心,所以我打算重新搞一搞 HTTP 協(xié)議,HTTP 協(xié)議對(duì)我們程序員來(lái)說(shuō)太重要了,不管你使用的是哪個(gè)語(yǔ)言,HTTP 都是你需要知道的重點(diǎn)。

這不是一篇簡(jiǎn)單介紹 HTTP 基本概念的文章,如果你對(duì) HTTP 基本概念不是很熟悉,推薦你去讀 cxuan 寫的關(guān)于 HTTP 基礎(chǔ)文章 - 看完這篇HTTP,跟面試官扯皮就沒(méi)問(wèn)題了

所以我們假定在做的各位對(duì) HTTP 有一定的了解和認(rèn)識(shí)。

下面開始我們這篇文章。

搭載 HTTP 的 TCP

我們大家都知道,HTTP 這個(gè)應(yīng)用層協(xié)議是以 TCP 為基礎(chǔ)來(lái)傳輸數(shù)據(jù)的。當(dāng)你想訪問(wèn)一個(gè)資源(資源在網(wǎng)絡(luò)中就是一個(gè) URL)時(shí),你需要先解析這個(gè)資源的 IP 地址和端口號(hào),從而和這個(gè) IP 和端口號(hào)所在的服務(wù)器建立 TCP 連接,然后 HTTP 客戶端發(fā)起服務(wù)請(qǐng)求(GET)報(bào)文,服務(wù)器對(duì)服務(wù)器的請(qǐng)求報(bào)文做出響應(yīng),等到不需要交換報(bào)文時(shí),客戶端會(huì)關(guān)閉連接,下面我用圖很好的說(shuō)明了這個(gè)過(guò)程。

上面這幅圖很好的說(shuō)明了 HTTP 從建立連接開始 -> 發(fā)起請(qǐng)求報(bào)文 -> 關(guān)閉連接的全過(guò)程,但是上面這個(gè)過(guò)程還忽略了一個(gè)很重要的點(diǎn),那就是TCP 建立連接的過(guò)程。

TCP 建立連接需要經(jīng)過(guò)三次握手,交換三個(gè)報(bào)文,我相信大家都對(duì)這個(gè)過(guò)程了然于胸了,如果你還不清楚 TCP 建立連接的過(guò)程,可以先閱讀 cxuan 的這篇文章 TCP 連接管理。

由于 HTTP 位于 TCP 的上層,所以 HTTP 的請(qǐng)求 -> 響應(yīng)過(guò)程的時(shí)效性(性能)很大程度上取決于底層 TCP 的性能,只有在了解了 TCP 連接的性能之后,才可以更好的理解 HTTP 連接的性能,從而才能夠?qū)崿F(xiàn)高性能的 HTTP 應(yīng)用程序。

我們通常把一次完整的請(qǐng)求 -> 相應(yīng)過(guò)程稱之為 HTTP 事務(wù)。

所以我后面一般會(huì)寫為 HTTP 事務(wù),你理解怎么回事就好。

我們接下來(lái)的重點(diǎn)要先從 TCP 的性能入手。

HTTP 時(shí)延損耗

再來(lái)回顧一下上面的 HTTP 事務(wù)的過(guò)程,你覺(jué)得有哪幾個(gè)過(guò)程會(huì)造成 HTTP 事務(wù)時(shí)延呢?如下圖所示

從圖中可以看出,主要是有下面這幾個(gè)因素影響 HTTP 事務(wù)的時(shí)延

  1. 客戶端會(huì)根據(jù) URL 確定服務(wù)器的 IP 和端口號(hào),這里主要是 DNS 把域名轉(zhuǎn)換為 IP 地址的時(shí)延,DNS 會(huì)發(fā)起 DNS 查詢,查詢服務(wù)器的 IP 地址。
  2. 第二個(gè)時(shí)延是 TCP 建立連接時(shí)會(huì)由客戶端向服務(wù)器發(fā)送連接請(qǐng)求報(bào)文,并等待服務(wù)器回送響應(yīng)報(bào)文的時(shí)延。每條新的 TCP 連接建立都會(huì)有建立時(shí)延。
  3. 一旦連接建立后,客戶端就會(huì)向服務(wù)器請(qǐng)求數(shù)據(jù),這個(gè)時(shí)延主要是服務(wù)器從 TCP 連接中讀取請(qǐng)求報(bào)文,并對(duì)請(qǐng)求進(jìn)行處理的時(shí)延。
  4. 服務(wù)器會(huì)向客戶端傳輸響應(yīng)報(bào)文的時(shí)延。
  5. 最后一個(gè)時(shí)延是 TCP 連接關(guān)閉的時(shí)延。

其中最后一點(diǎn)的優(yōu)化也是本文想要討論的一個(gè)重點(diǎn)。

HTTP 連接管理

試想一個(gè)問(wèn)題,假設(shè)一個(gè)頁(yè)面有五個(gè)資源(元素),每個(gè)資源都需要客戶端打開一個(gè) TCP 連接、獲取資源、斷開連接,而且每個(gè)連接都是串行打開的,如下圖所示:

串行的意思就是,這五個(gè)連接必須是有先后順序,不會(huì)出現(xiàn)同時(shí)有兩個(gè)以上的連接同時(shí)打開的情況。

上面五個(gè)資源就需要打開五條連接,資源少還好說(shuō),CPU 能夠處理,如果頁(yè)面資源達(dá)到上百或者更多的時(shí)候呢?每個(gè)資源還需要單獨(dú)再打開一條連接嗎?這樣顯然會(huì)急劇增加 CPU 的處理壓力,造成大量的時(shí)延,顯然是沒(méi)有必要的。

串行還有一個(gè)缺點(diǎn)就是,有些瀏覽器在對(duì)象加載完畢之前是無(wú)法知道對(duì)象的尺寸(size)的,并且瀏覽器需要對(duì)象尺寸信息來(lái)將他們放在屏幕中合理的位置上,所以在加載了足夠多的對(duì)象之前,屏幕是不會(huì)顯示任何內(nèi)容的,這就會(huì)造成,其實(shí)對(duì)象一直在加載,但是我們以為瀏覽器卡住了。

所以,有沒(méi)有能夠優(yōu)化 HTTP 性能的方式呢?這個(gè)問(wèn)題問(wèn)得好,當(dāng)然是有的。

并行連接

這是一種最常見的,也是最容易想到的一種連接方式,HTTP 允許客戶端打開多條連接,并行執(zhí)行多個(gè) HTTP 事務(wù),加入并行連接后,整個(gè) HTTP 事務(wù)的請(qǐng)求過(guò)程是這樣的。

采用并行連接這種方式會(huì)克服單條連接的空載時(shí)間和帶寬限制,因?yàn)槊總€(gè)事務(wù)都有連接,因此時(shí)延能夠重疊起來(lái),會(huì)提高頁(yè)面的加載速度。

但是并行連接并不一定快,如果帶寬不夠的情況下,甚至頁(yè)面響應(yīng)速度還不如串行連接,因?yàn)樵诓⑿羞B接中,每個(gè)連接都會(huì)去競(jìng)爭(zhēng)使用有效的帶寬,每個(gè)對(duì)象都會(huì)以較慢的速度加載,有可能連接 1 加載了 95% ,連接 2 占用帶寬加載了 80%,連接 3 ,連接 4 。。。。。。雖然每個(gè)對(duì)象都在加載,但是頁(yè)面上卻沒(méi)有任何響應(yīng)。

而且,打開大量連接會(huì)消耗很多內(nèi)存資源,從而出現(xiàn)性能問(wèn)題,上面討論的就五個(gè)連接,這個(gè)還比較少,復(fù)雜的 web 頁(yè)面有可能會(huì)有數(shù)十甚至數(shù)百個(gè)內(nèi)嵌對(duì)象,也就是說(shuō),客戶端可以打開數(shù)百個(gè)連接,而且有許多的客戶端同時(shí)發(fā)出申請(qǐng),這樣很容易會(huì)成為性能瓶頸。

這樣看來(lái),并行連接并不一定"快",實(shí)際上并行連接并沒(méi)有加快頁(yè)面的傳輸速度,并行連接也只是造成了一種假象,這是一切并行的通病。

持久連接

Web 客戶端通常會(huì)打開到同一個(gè)站點(diǎn)的連接,而且初始化了對(duì)某服務(wù)器請(qǐng)求的應(yīng)用程序很可能會(huì)在不久的將來(lái)對(duì)這臺(tái)服務(wù)器發(fā)起更多的請(qǐng)求,比如獲取更多的圖片。這種特性被稱為站點(diǎn)局部性(site locality)。

因此,HTTP 1.1 以及 HTTP1.0 的允許 HTTP 在執(zhí)行完一次事務(wù)之后將連接繼續(xù)保持在打開狀態(tài),這個(gè)打開狀態(tài)其實(shí)指的就是 TCP 的打開狀態(tài),以便于下一次的 HTTP 事務(wù)能夠復(fù)用這條連接。

在一次 HTTP 事務(wù)結(jié)束之后仍舊保持打開狀態(tài)的 TCP 連接被稱為持久連接。

非持久連接會(huì)在每個(gè)事務(wù)結(jié)束之后關(guān)閉,相對(duì)的,持久連接會(huì)在每個(gè)事務(wù)結(jié)束之后繼續(xù)保持打開狀態(tài)。持久連接會(huì)在不同事務(wù)之間保持打開狀態(tài),直到客戶端或者服務(wù)器決定將其關(guān)閉為止。

長(zhǎng)連接也是有缺點(diǎn)的,如果單一客戶端發(fā)起請(qǐng)求數(shù)量不是很頻繁,但是連接的客戶端卻有很多的話,服務(wù)器早晚會(huì)有崩潰的時(shí)候。

持久連接一般有兩種選型方式,一種是 HTTP 1.0 + keep-alive ;一種是 HTTP 1.1 + persistent。

HTTP 1.1 之前的版本默認(rèn)連接都是非持久連接,如果想要在舊版本的 HTTP 上使用持久連接,需要指定 Connection 的值為 Keep-Alive。

HTTP 1.1 版本都是持久性連接,如果想要斷開連接時(shí),需要指定 Connection 的值為 close,這也是我們上面說(shuō)的兩種選型方式的版本因素。

下面是使用了持久連接之后的 HTTP 事務(wù)與使用串行 HTTP 事務(wù)連接的對(duì)比圖

這張圖對(duì)比了 HTTP 事務(wù)在串行連接上和持久連接的時(shí)間損耗圖,可以看到,HTTP 持久連接省去了連接打開 - 連接關(guān)閉的時(shí)間,所以在時(shí)間損耗上有所縮減。

在持久性連接中,還有一個(gè)非常有意思的地方,就是 Connection 選項(xiàng),Connection 是一個(gè)通用選項(xiàng),也就是客戶端和服務(wù)端都具有的一個(gè)標(biāo)頭,下面是一個(gè)具有持久性連接的客戶端和服務(wù)端的請(qǐng)求-響應(yīng)圖

從這張圖可以看出,持久連接主要使用的就是 Connection 標(biāo)頭,這也就意味著,Connection 就是持久性連接的實(shí)現(xiàn)方式。所以下面我們主要討論一下 Connection 這個(gè)大佬。

Connection 標(biāo)頭

Connection 標(biāo)頭具有兩種作用

  • 和 Upgrade 一起使用進(jìn)行協(xié)議升級(jí)
  • 管理持久連接

和 Upgrade 一起使用進(jìn)行協(xié)議升級(jí)

HTTP 提供了一種特殊的機(jī)制,這一機(jī)制允許將一個(gè)已建立的連接升級(jí)成新的協(xié)議,一般寫法如下

  1. GET /index.html HTTP/1.1 
  2. Host: www.example.com 
  3. Connection: upgrade 
  4. Upgrade: example/1, foo/2 

HTTP/2 明確禁止使用此機(jī)制,這個(gè)機(jī)制只屬于HTTP/1.1

也就是說(shuō),客戶端發(fā)起 Connection:upgrade 就表明這是一個(gè)連接升級(jí)的請(qǐng)求,如果服務(wù)器決定升級(jí)這次連接,就會(huì)返回一個(gè) 101 Switching Protocols 響應(yīng)狀態(tài)碼,和一個(gè)要切換到的協(xié)議的頭部字段 Upgrade。如果服務(wù)器沒(méi)有(或者不能)升級(jí)這次連接,它會(huì)忽略客戶端發(fā)送的 Upgrade 頭部字段,返回一個(gè)常規(guī)的響應(yīng):例如返回 200。

管理持久連接

我們上面說(shuō)持久連接有兩種方式,一種是 HTTP 1.0 + Keep-Alive ;一種是 HTTP 1.1 + persistent。

  1. Connection: Keep-Alive 
  2. Keep-Alive: timeout=10,max=500 

在 HTTP 1.0 + Keep-Alive 這種方式下,客戶端可以通過(guò)包含 Connection:Keep-Alive 首部請(qǐng)求將一條連接保持在打開狀態(tài)。

這里需要注意??一點(diǎn):Keep-Alive 首部只是將請(qǐng)求保持在活躍狀態(tài),發(fā)出 Keep-Alive 請(qǐng)求之后,客戶端和服務(wù)器不一定會(huì)同意進(jìn)行 Keep-Alive 會(huì)話。它們可以在任何時(shí)刻關(guān)閉空閑的 Keep-Alive 連接,并且客戶端和服務(wù)器可以限制 Keep-Alive 連接所處理事務(wù)的數(shù)量。

Keep-Alive 這個(gè)標(biāo)頭有下面幾種選項(xiàng):

  • timeout:這個(gè)參數(shù)估計(jì)了服務(wù)器希望將連接保持在活躍狀態(tài)的時(shí)間。
  • max :這個(gè)參數(shù)是跟在 timeout 參數(shù)后面的,它表示的是服務(wù)器還能夠?yàn)槎嗌賯€(gè)事務(wù)打開持久連接。

Keep-Alive 這個(gè)首部是可選的,但是只有在提供 Connection:Keep-Alive 時(shí)才能使用它。

Keep-Alive 的使用有一定限制,下面我們就來(lái)討論一下 Keep-Alive 的使用限制問(wèn)題。

Keep-Alive 使用限制和規(guī)則

  • 在 HTTP/1.0 中,Keep-Alive 并不是默認(rèn)使用的,客戶端必須發(fā)送一個(gè) Connection:Keep-Alive 請(qǐng)求首部來(lái)激活 Keep-Alive 連接。
  • 通過(guò)檢測(cè)響應(yīng)中是否含有 Connection:Keep-Alive 首部字段,客戶端可以判斷服務(wù)器是否在發(fā)出響應(yīng)之后關(guān)閉連接。
  • 代理和網(wǎng)管必須執(zhí)行 Connection 首部規(guī)則,它們必須在將報(bào)文轉(zhuǎn)發(fā)出去或者將緩存之前,刪除 Connection 首部中的首部字段和 Connection 首部自身,因?yàn)?Connection 是一個(gè) Hop-by-Hop 首部,這個(gè)首部說(shuō)的是只對(duì)單次轉(zhuǎn)發(fā)有效,會(huì)因?yàn)檗D(zhuǎn)發(fā)給緩存/代理服務(wù)器而失效。
  • 嚴(yán)格來(lái)說(shuō),不應(yīng)該與無(wú)法確定是否支持 Connection 首部的代理服務(wù)器建立 Keep-Alive 連接,以防止出現(xiàn)啞代理問(wèn)題,啞代理問(wèn)題我們下面會(huì)說(shuō)。

Keep-Alive 和啞代理問(wèn)題

這里我先解釋一下什么是代理服務(wù)器,然后再說(shuō)啞代理問(wèn)題。

什么是代理服務(wù)器?

代理服務(wù)器就是代替客戶端去獲取網(wǎng)絡(luò)信息的一種媒介,通俗一點(diǎn)就是網(wǎng)絡(luò)信息的中轉(zhuǎn)站。

為什么我們需要代理服務(wù)器?

最廣泛的一種用處是我們需要使用代理服務(wù)器來(lái)替我們?cè)L問(wèn)一些我們客戶端無(wú)法直接訪問(wèn)的網(wǎng)站。除此之外,代理服務(wù)器還有很多功能,比如緩存功能,可以降低費(fèi)用,節(jié)省帶寬;對(duì)信息的實(shí)時(shí)監(jiān)控和過(guò)濾,代理服務(wù)器相對(duì)于目標(biāo)服務(wù)器(最終獲取信息的服務(wù)器)來(lái)說(shuō),也是一個(gè)客戶端,它能夠獲取服務(wù)器提供的信息,代理服務(wù)器相對(duì)于客戶端來(lái)說(shuō),它是一個(gè)服務(wù)器,由它來(lái)決定提供哪些信息給客戶端,以此來(lái)達(dá)到監(jiān)控和過(guò)濾的功能。

啞代理問(wèn)題出現(xiàn)就出現(xiàn)在代理服務(wù)器上,再細(xì)致一點(diǎn)就是出現(xiàn)在不能識(shí)別 Connection 首部的代理服務(wù)器,而且不知道在發(fā)出請(qǐng)求之后會(huì)刪除 Connection 首部的代理服務(wù)器。

假設(shè)一個(gè) Web 客戶端正在通過(guò)一個(gè)啞代理服務(wù)器與 Web 服務(wù)器進(jìn)行對(duì)話,如下圖所示

來(lái)解釋一下上面這幅圖

  • 首先,Web 客戶端向代理發(fā)送了一條報(bào)文,其中包含了 Connection: Keep-Alive 首部,希望在這次 HTTP 事務(wù)之后繼續(xù)保持活躍狀態(tài),然后客戶端等待響應(yīng),以確定對(duì)方是否允許持久連接。
  • 啞代理(這里先界定為啞代理是不妥的,我們往往先看做的事,再給這件事定性,現(xiàn)在這個(gè)服務(wù)器還沒(méi)做出啞代理行為呢,就給他定性了)收到了這條 HTTP 請(qǐng)求,但它不理解 Connection 首部,它也不知道 Keep-Alive 是什么意思,因此只是沿著轉(zhuǎn)發(fā)鏈路將報(bào)文發(fā)送給服務(wù)器,但 Connection 首部是個(gè) Hop-by-Hop 首部,只適用于單條鏈路傳輸,所以這個(gè)代理服務(wù)器不應(yīng)該再將其發(fā)送給服務(wù)器了,但是它還是發(fā)送了,后面就會(huì)發(fā)生一些難頂?shù)氖虑椤?/li>
  • 經(jīng)過(guò)轉(zhuǎn)發(fā)的 HTTP 請(qǐng)求到達(dá)服務(wù)器后,會(huì)誤以為對(duì)方希望保持 Keep-Alive 持久連接,經(jīng)過(guò)評(píng)估后,服務(wù)器作出響應(yīng),它同意進(jìn)行 Keep-Alive 對(duì)話,所以它回送了一個(gè) Connection:Keep-Alive 響應(yīng)并到達(dá)了啞代理服務(wù)器。
  • 啞代理服務(wù)器會(huì)直接將響應(yīng)發(fā)送給客戶端,客戶端收到響應(yīng)后,就知道服務(wù)器可以使用持久連接。然而,此時(shí)客戶端和服務(wù)器都知道要使用 Keep-Alive 持久連接,但是啞代理服務(wù)器卻對(duì) Keep-Alive 一無(wú)所知。
  • 由于代理對(duì) Keep-Alive 一無(wú)所知,所以會(huì)收到的所有數(shù)據(jù)都會(huì)發(fā)送給客戶端,然后等待服務(wù)器關(guān)閉連接,但是代理服務(wù)器卻認(rèn)為應(yīng)該保持打開狀態(tài),所以不會(huì)去關(guān)閉連接。這樣,啞代理服務(wù)器就一直掛在那里等待連接的關(guān)閉。
  • 等到客戶端發(fā)送下一個(gè) HTTP 事務(wù)后,啞代理會(huì)直接忽視新的 HTTP 事務(wù),因?yàn)樗⒉徽J(rèn)為一條連接上還會(huì)有其他請(qǐng)求的到來(lái),所以會(huì)直接忽略新的請(qǐng)求。

這就是 Keep-Alive 的啞代理。

那么如何解決這個(gè)問(wèn)題呢?用 Proxy-Connection

Proxy-Connection 解決啞代理

網(wǎng)景公司提出了一種使用 Proxy-Connection 標(biāo)頭的辦法,首先瀏覽器會(huì)向代理發(fā)送 Proxy-Connection 擴(kuò)展首部,而不是官方支持的 Connection 首部。如果代理服務(wù)器是啞代理的話,它會(huì)直接將 Proxy-Connection 發(fā)送給服務(wù)器,而服務(wù)器收到 Proxy-Connection 的話,就會(huì)忽略這個(gè)首部,這樣不會(huì)帶來(lái)任何問(wèn)題。如果是一個(gè)聰明的代理服務(wù)器,在收到 Proxy-Connection 的時(shí)候,就會(huì)直接將 Connection 替換掉 Proxy-Connection ,再發(fā)送給服務(wù)器。

HTTP/1.1 持久連接

HTTP/1.1 逐漸停止了對(duì) Keep-Alive 連接的支持,用一種名為 persistent connection 的改進(jìn)型設(shè)計(jì)取代了 Keep-Alive ,這種改進(jìn)型設(shè)計(jì)也是持久連接,不過(guò)比 HTTP/1.0 的工作機(jī)制更優(yōu)。

與 HTTP/1.0 的 Keep-Alive 連接不同,HTTP/1.1 在默認(rèn)情況下使用的就是持久連接。除非特別指明,否則 HTTP/1.1 會(huì)假定所有連接都是持久連接。如果想要在事務(wù)結(jié)束后關(guān)閉連接的話,就需要在報(bào)文中顯示添加一個(gè) Connection:close 首部。這是與以前的 HTTP 協(xié)議版本很重要的區(qū)別。

使用 persistent connection 也會(huì)有一些限制和規(guī)則:

  • 首先,發(fā)送了 Connection: close 請(qǐng)求后,客戶端就無(wú)法在這條連接上發(fā)送更多的請(qǐng)求。這同時(shí)也可以說(shuō),如果客戶端不想發(fā)送其他請(qǐng)求,就可以使用 Connection:close 關(guān)閉連接。
  • HTTP/1.1 的代理必須能夠分別管理客戶端和服務(wù)器的持久連接 ,每個(gè)持久連接都只適用于單次傳輸。
  • 客戶端對(duì)任何服務(wù)器或者代理最好只維護(hù)兩條持久連接,以防止服務(wù)器過(guò)載。
  • 只有實(shí)體部分的長(zhǎng)度和相應(yīng)的 Content-Length保持一致時(shí),或者使用分塊傳輸編碼的方式時(shí),連接才能保持長(zhǎng)久。

管道化連接

HTTP/1.1 允許在持久連接上使用請(qǐng)求管道。這是相對(duì)于 Keep-Alive 連接的又一個(gè)性能優(yōu)化。管道就是一個(gè)承載 HTTP 請(qǐng)求的載體,我們可以將多個(gè) HTTP 請(qǐng)求放入管道,這樣能夠降低網(wǎng)絡(luò)的環(huán)回時(shí)間,提升性能。下圖是使用串行連接、并行連接、管道化連接的示意圖:

使用管道化的連接也有幾處限制:

  • 如果 HTTP 客戶端無(wú)法確認(rèn)連接是持久的,就不應(yīng)該使用管道。
  • 必須按照與請(qǐng)求的相同順序回送 HTTP 響應(yīng),因?yàn)?HTTP 沒(méi)有序號(hào)這個(gè)概念,所以一旦響應(yīng)失序,就沒(méi)辦法將其與請(qǐng)求匹配起來(lái)了。
  • HTTP 客戶端必須做好連接會(huì)在任何時(shí)刻關(guān)閉的準(zhǔn)備,還要準(zhǔn)備好重發(fā)所有未完成的管道化請(qǐng)求。

HTTP 關(guān)閉連接

所有 HTTP 客戶端、服務(wù)器或者代理都可以在任意時(shí)刻關(guān)閉一條 HTTP 傳輸連接。通常情況下會(huì)在一次響應(yīng)后關(guān)閉連接,但是保不準(zhǔn)也會(huì)在 HTTP 事務(wù)的過(guò)程中出現(xiàn)。

但是,服務(wù)器無(wú)法確定在關(guān)閉的那一刻,客戶端有沒(méi)有數(shù)據(jù)要發(fā)送,如果出現(xiàn)這種情況,客戶端就會(huì)在進(jìn)行數(shù)據(jù)傳輸?shù)倪^(guò)程中發(fā)生了寫入錯(cuò)誤。

即使在不出錯(cuò)的情況下,連接也可以在任意時(shí)刻關(guān)閉。如果在事務(wù)傳輸?shù)倪^(guò)程中出現(xiàn)了連接關(guān)閉情況,就需要重新打開連接進(jìn)行重試。如果是單條連接還好說(shuō),如果是管道化連接,就比較糟糕,因?yàn)楣艿阑B接會(huì)把大量的連接丟在管道中,此時(shí)如果服務(wù)器關(guān)閉,就會(huì)造成大量的連接未響應(yīng),需要重新調(diào)度。

如果一個(gè) HTTP 事務(wù)不管執(zhí)行一次還是執(zhí)行 n 次,它得到的結(jié)果始終是一樣的,那么我們就認(rèn)為這個(gè)事務(wù)是冪等的,一般 GET、HEAD、PUT、DELETE、TRACE 和 OPTIONS方法都認(rèn)為是冪等的??蛻舳瞬粦?yīng)該以管道化的方式發(fā)送任何非冪等請(qǐng)求,比如 POST,否則就會(huì)造成不確定的后果。

由于 HTTP 使用 TCP 作為傳輸層的協(xié)議,所以 HTTP 關(guān)閉連接其實(shí)還是 TCP 關(guān)閉連接的過(guò)程。

HTTP 關(guān)閉連接一共分為三種情況:完全關(guān)閉、半關(guān)閉和正常關(guān)閉。

應(yīng)用程序可以關(guān)閉 TCP 輸入和輸出信道中的任何一個(gè),或者將二者同時(shí)關(guān)閉。調(diào)用套接字 close() 方法會(huì)講輸入和輸出同時(shí)關(guān)閉,這就被稱為完全關(guān)閉。還可以調(diào)用套接字的 shutdown 方法單獨(dú)關(guān)閉輸入或者輸出信道,這被稱為半關(guān)閉。HTTP 規(guī)范建議當(dāng)客戶端和服務(wù)器突然需要關(guān)閉連接的時(shí)候,應(yīng)該正常關(guān)閉,但是它沒(méi)有說(shuō)如何去做。

本文轉(zhuǎn)載自微信公眾號(hào)「程序員cxuan」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系程序員cxuan公眾號(hào)。

 

責(zé)任編輯:武曉燕 來(lái)源: 程序員cxuan
相關(guān)推薦

2021-08-03 09:33:55

HTTP網(wǎng)絡(luò)協(xié)議TCP

2010-06-13 15:37:24

TCP協(xié)議

2022-03-21 14:27:22

管理市場(chǎng)物聯(lián)網(wǎng)IOT

2009-04-07 11:08:49

2009-11-11 17:24:59

ADO.NET連接管理

2010-06-10 15:14:32

TCP傳輸控制協(xié)議

2018-07-12 15:30:03

HTTP緩存機(jī)制

2024-12-04 16:12:31

2020-09-28 06:48:15

HTTP協(xié)議版本

2015-10-09 15:07:02

HTTP網(wǎng)絡(luò)協(xié)議

2019-04-01 07:31:29

物聯(lián)網(wǎng)平臺(tái)物聯(lián)網(wǎng)IOT

2023-06-01 07:56:48

SQLAlchemy數(shù)據(jù)庫(kù)

2018-10-09 09:28:12

HTTPHTTP協(xié)作服務(wù)器

2011-08-11 10:02:11

windows7遠(yuǎn)程連接管理服務(wù)

2021-12-30 07:42:13

Kubernetes集群架構(gòu)

2021-01-11 05:40:18

HTTPHTTP 協(xié)議網(wǎng)絡(luò)技術(shù)

2010-09-14 15:30:27

2018-06-06 11:01:25

HTTP長(zhǎng)連接短連接

2019-04-15 14:37:23

HTTPTCP長(zhǎng)連接

2016-07-14 14:28:52

華為
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)