?
This document uses PHP Chinese website manual Release
連接管理是HTTP中的一個關(guān)鍵主題:打開和維護(hù)連接主要影響Web站點(diǎn)和Web應(yīng)用程序的性能。在HTTP / 1.x中,有幾種模式:短暫連接,持久連接和HTTP流水線。
HTTP主要依賴于TCP的傳輸協(xié)議,在客戶端和服務(wù)器之間提供連接。在初期,HTTP使用單一模型來處理這種連接。這些連接是短暫的:每次請求需要發(fā)送時創(chuàng)建一個新連接,并在收到答復(fù)后關(guān)閉。
這個簡單的模型對性能有著天生的限制:打開每個TCP連接是耗費(fèi)資源的操作。必須在客戶端和服務(wù)器之間交換幾條消息。當(dāng)請求需要發(fā)送時,網(wǎng)絡(luò)延遲和帶寬會影響性能?,F(xiàn)代網(wǎng)頁需要許多請求(十幾個或更多)來提供所需的信息量,證明這種早期模型效率低下。
HTTP / 1.1中創(chuàng)建了兩個較新的模型。持久連接模型保持連續(xù)請求之間的連接打開,減少打開新連接所需的時間。HTTP流水線模型更進(jìn)一步,通過發(fā)送幾個連續(xù)的請求,甚至不用等待答案,減少了網(wǎng)絡(luò)中的大部分延遲。
HTTP / 2添加了用于連接管理的其他模型。
需要注意的一點(diǎn)是,HTTP中的連接管理適用于兩個連續(xù)節(jié)點(diǎn)之間的連接,即逐跳而不是端到端。用于客戶端與其第一個代理之間連接的模型可能與代理與目標(biāo)服務(wù)器(或任何中間代理)之間的模型不同。參與定義的連接模型,如HTTP標(biāo)頭Connection
和Keep-Alive
,是逐跳頭與他們的價值觀能夠通過中間節(jié)點(diǎn)進(jìn)行更改。
一個相關(guān)的主題是HTTP連接升級的概念,其中HTTP / 1.1連接升級為不同的協(xié)議,例如TLS / 1.0,WebSocket甚至HTTP / 2的明文。此協(xié)議升級機(jī)制在其他地方有更詳細(xì)的記錄。
HTTP的原始模型和HTTP / 1.0中的默認(rèn)模型是短暫的連接。每個HTTP請求都在其自己的連接上完成; 這意味著TCP握手在每個HTTP請求之前發(fā)生,并且這些都是序列化的。
TCP握手本身非常耗時,但TCP連接適應(yīng)其負(fù)載,在連接更持久(或溫暖)的情況下變得更高效。短暫的連接不利用TCP的這種效率特性,并且通過堅持通過新的冷連接進(jìn)行傳輸而使性能從最佳狀態(tài)下降。
該模型是HTTP / 1.0中使用的默認(rèn)模型(如果沒有Connection
標(biāo)題或者其值設(shè)置為close
)。在HTTP / 1.1中,這個模型只有在Connection
頭文件的值為close
。
除非處理一個不支持持續(xù)連接的非常舊的系統(tǒng),否則沒有令人信服的理由來使用此模型。
短暫連接有兩個主要問題:建立新連接所花費(fèi)的時間非常長,并且只有在此連接已使用一段時間(熱連接)時,底層TCP連接的性能才會更好。為了緩解這些問題,設(shè)計了持久連接的概念,甚至在HTTP / 1.1之前?;蛘?,這可以被稱為保持連接。
持續(xù)連接是一段時間內(nèi)保持打開的狀態(tài),可以重復(fù)使用多個請求,從而節(jié)省了對新的TCP握手的需求,并利用TCP的性能增強(qiáng)功能。此連接不會永遠(yuǎn)保持打開狀態(tài):閑置連接在一段時間后關(guān)閉(服務(wù)器可能會使用Keep-Alive
標(biāo)題指定連接應(yīng)保持打開的最短時間)。
持續(xù)連接也有缺點(diǎn); 即使在閑置時也會占用服務(wù)器資源,并且在高負(fù)載下可以執(zhí)行DoS攻擊。在這種情況下,使用非持久連接,一旦空閑就關(guān)閉,可以提供更好的性能。
HTTP / 1.0連接默認(rèn)情況下不持久。通常設(shè)置Connection
為其他任何東西都會使它們持久。closeretry-after
在HTTP / 1.1中,持久性是默認(rèn)的,并且不再需要頭(但它通常被添加為防止需要回退到HTTP / 1.0的情況的防御措施)。
在現(xiàn)代瀏覽器中,缺省情況下HTTP流水線不會被激活:
Buggy 代理仍然很常見,并且這些會導(dǎo)致Web開發(fā)人員無法輕易預(yù)見和診斷的奇怪且不穩(wěn)定的行為。
流水線執(zhí)行起來很復(fù)雜:正在傳輸?shù)馁Y源的大小,將要使用的有效RTT以及有效帶寬,都直接影響到流水線提供的改進(jìn)。如果不知道這些,重要的信息可能會被拖延到不重要的信息后面。重要的概念甚至在頁面布局中發(fā)展!因此,HTTP流水線在大多數(shù)情況下只會帶來一些改進(jìn)。
流水線服從HOL問題。
由于這些原因,流水線已經(jīng)被HTTP / 2使用的更好的算法 - 多路復(fù)用所取代。
默認(rèn)情況下,HTTP請求按順序發(fā)出。下一個請求只有在收到對當(dāng)前請求的響應(yīng)后才會發(fā)出。由于它們受到網(wǎng)絡(luò)延遲和帶寬限制的影響,因此在服務(wù)器看到下一個請求之前,可能會導(dǎo)致嚴(yán)重的延遲。
流水線是通過相同的持續(xù)連接發(fā)送連續(xù)請求而不等待答案的過程,這避免了連接的延遲。從理論上講,如果將兩個HTTP請求打包到同一個TCP消息中,性能也可以提高。典型的MSS(最大段大小)大到足以包含幾個簡單的請求,盡管HTTP請求的大小需求會持續(xù)增長。
并非所有類型的HTTP請求可以為流水線:而僅僅是冪等方法,即GET
,HEAD
,PUT
和DELETE
,可以安全地重播:管道的內(nèi)容應(yīng)該在故障發(fā)生時可以簡單地重復(fù)。
今天,每個HTTP / 1.1兼容的代理和服務(wù)器應(yīng)該支持流水線操作,盡管許多實(shí)踐中有一些限制:一個重要的原因是沒有現(xiàn)代瀏覽器在默認(rèn)情況下激活此功能。
除非你有一個非常具體的直接需求,否則不要使用這個棄用的技術(shù); 改為切換到HTTP / 2。在HTTP / 2中,域分片不再有用:HTTP / 2連接能夠非常好地處理并行未重要的請求。域分片甚至對性能不利。大多數(shù)HTTP / 2實(shí)現(xiàn)使用稱為連接合并的技術(shù)來恢復(fù)最終的域分片。
由于HTTP / 1.x連接正在序列化請求,即使沒有任何排序,如果沒有足夠的可用帶寬,它也不會是最佳的。作為一種解決方案,瀏覽器打開幾個連接到每個域,發(fā)送并行請求。默認(rèn)情況下是2到3次連接,但現(xiàn)在已經(jīng)增加到更常見的6個并行連接。如果嘗試超過這個數(shù)字,可能會在服務(wù)器端觸發(fā)DoS保護(hù)。
如果服務(wù)器希望獲得更快的網(wǎng)站或應(yīng)用程序響應(yīng),則服務(wù)器可能會強(qiáng)制打開更多連接。例如,而不必在同一域中的所有資源,比如說www.example.com
,它可以拆分成幾個域www1.example.com
,www2.example.com
,www3.example.com
。每個域都解析為同一臺服務(wù)器,Web瀏覽器將打開6個連接(在我們的示例中,將連接提升到18)。這種技術(shù)被稱為域分片。
改進(jìn)的連接管理可以顯著提高HTTP的性能。使用HTTP / 1.1或HTTP / 1.0與持久連接 - 至少在其變?yōu)榭臻e狀態(tài)之前 - 因?yàn)檫@樣可以獲得最佳性能。然而,流水線的失敗已經(jīng)導(dǎo)致設(shè)計出優(yōu)秀的連接管理模型,這些模型已經(jīng)被合并到HTTP / 2中。