HTTP中的連接管理是一個(gè)關(guān)鍵性話題,持久的打開連接極大的影響著網(wǎng)站和web應(yīng)用的性能带污,在HTTP/1.x中体箕,有這么幾種模型:short-lived 連接,persistent 連接和HTTP pipelining杈笔。
HTTP 極大的依賴于TCP協(xié)議闪水,HTTP 初期只使用short-lived模式處理連接:每次請(qǐng)求創(chuàng)建一個(gè)連接,響應(yīng)結(jié)束則關(guān)閉連接蒙具。
這種簡(jiǎn)陋的模式在性能上天生就有缺陷:每打開一個(gè)TCP連接都是一個(gè)耗費(fèi)資源的操作球榆,網(wǎng)絡(luò)延遲和帶寬限制都會(huì)影響性能朽肥;而現(xiàn)在的許多web頁面獲取完整的信息需要發(fā)送十幾個(gè)請(qǐng)求,這證明早期的模型是無效的芜果。
在HTTP/1.1有兩種新模型鞠呈;持久連接(persistent-connection)模式可以保持請(qǐng)求成功了的連接一直處于打開狀態(tài),從而減少了建立連接的開銷右钾。管道連接(pipelining)模式更進(jìn)一步蚁吝,可以連續(xù)發(fā)送幾個(gè)請(qǐng)求,這些請(qǐng)求甚至不需要等待服務(wù)器的響應(yīng)舀射,可參考下圖:
HTTP/2 使用特有的連接管理模式
需要指出的是:http的連接管理是針對(duì)兩個(gè)連續(xù)的逐跳(hop-by-hop)節(jié)點(diǎn)窘茁,非端到端(end-to-end);客戶端和第一代理之間使用的連接模式可能取決于第二或第三代理和目標(biāo)服務(wù)器之間的連接模式脆烟。HTTP headers可以定義使用哪種連接模式山林,比如Connection
和Keep-Alive
,它們屬于hop-by-hop headers 邢羔,同時(shí)可以被中間節(jié)點(diǎn)改變驼抹。
另一個(gè)相關(guān)的話題是HTTP連接的升級(jí),在HTTP/1.1中使用的是如TLS/1.0拜鹤、WebSocket框冀、甚至協(xié)議進(jìn)行升級(jí),更多可參考 協(xié)議升級(jí)機(jī)制敏簿;
短連接 Short-lived connections
HTTP的最初模型明也,甚至HTTP/1.0都是短連接模式,每個(gè)HTTP請(qǐng)求都是在它自己的連接上完成的惯裕,這意味著每個(gè)請(qǐng)求都需要三次握手温数,并且它們都是竄行(非并行)的。三次握手本身就需要耗費(fèi)時(shí)間蜻势,但是TCP連接適應(yīng)了這種負(fù)載撑刺,并且變得越來越高效和持久。TCP的特性本身不適用于短連接咙边,當(dāng)建立新的連接來持久傳輸會(huì)降低性能猜煮。
在HTTP/1.0中默認(rèn)使用這種模式(如果沒有指定Connection
header,或沒有設(shè)定為close
). 在HTTP/1.1中败许,只有當(dāng)Connection
header設(shè)置為close
才會(huì)啟用短連接王带。
除非處理一個(gè)不支持持久連接的舊系統(tǒng),否則沒有可以令人信服的理由使用這個(gè)模型市殷。
持久連接 Persistent connections
短連接有兩個(gè)主要的障礙:花費(fèi)在建立新連接的時(shí)間巨多愕撰;只有當(dāng)TCP連接被用于暖連接時(shí)性能才會(huì)變得更好。為了解決這兩個(gè)問題,持久連接誕生了搞挣,甚至在HTTP/1.1之前就有這個(gè)概念带迟,持戒連接也被稱為keep-alive連接。
持久連接可以被重復(fù)利用很多次囱桨,可以節(jié)省重復(fù)建立TCP的時(shí)間仓犬,最大化的優(yōu)化其性能。但是持久連接并不是說永遠(yuǎn)都處于打開的狀態(tài):服務(wù)端可以利用 Keep-Alive
請(qǐng)求頭指定一個(gè)最小打開時(shí)間舍肠;
但持久連接也是有缺陷的搀继,甚至當(dāng)空轉(zhuǎn)的時(shí)候,也消耗服務(wù)端的資源于負(fù)荷翠语,DoS attacks攻擊能夠利用這個(gè)缺陷叽躯。在這種情況下,非持久連接就更高效了肌括,一旦連接是空閑的点骑,就立刻關(guān)閉。
HTTP/1.0中使用的并非持久連接谍夭,將Connection
設(shè)置為非 close
, 然后使用retry-after
, 可以達(dá)到持久的目的黑滴;在HTTP/1.1中,默認(rèn)使用持久連接紧索,并且不用請(qǐng)求頭指定(but it is often added as a defensive measure against cases requiring a fallback to HTTP/1.0)跷跪;
流水線 HTTP pipelining
流水線模式在現(xiàn)在的瀏覽器中是沒有被激活的:
- 小車代理(Buggy proxies)仍然很常見并且導(dǎo)致web開發(fā)者不能預(yù)見很診斷一些奇奇怪怪的問題。
- 流水線模式要正確應(yīng)用起來是很復(fù)雜的:大量的資源需要傳輸齐板,RTT要高效實(shí)用,還有極速的帶寬葛菇,這些因素對(duì)該模式有直接的影響甘磨。不了解這些,恐怕使會(huì)得重要的消息被丟失眯停。因此該模式在大多數(shù)情況下只帶來了微小的改進(jìn)济舆;
- 該模式是 HOL 難題的主題。
基于以上理由莺债,該模式被HTTP/2中更好的算法和方案所取代滋觉。
所以默認(rèn)情況下,HTTP請(qǐng)求是有序的發(fā)送齐邦,下一個(gè)HTTP請(qǐng)求的發(fā)送要基于上一個(gè)請(qǐng)求已被響應(yīng)椎侠。由于網(wǎng)絡(luò)延遲和帶寬限制,這將導(dǎo)致請(qǐng)求的重大延遲措拇。
HTTP Pipelining 是在持久連接的基礎(chǔ)上可異步的發(fā)送請(qǐng)求我纪,這避免了連接的延遲,理論上,如果兩個(gè)HTTP請(qǐng)求包裹在同一個(gè)TCP消息管道中浅悉,性能將會(huì)得到很大的提升趟据。典型的MSS (Maximum Segment Size),可以攜帶若干個(gè)簡(jiǎn)單的HTTP請(qǐng)求术健,盡管HTTP請(qǐng)求數(shù)量的需求在不斷的增長汹碱。
并非所有類型的HTTP請(qǐng)求都可以使用該模式:只有idempotent方法,如 GET
, HEAD
, PUT
and DELETE
方法荞估,可以安全的被處理咳促。
如今,盡管現(xiàn)在大多數(shù)瀏覽器默認(rèn)不啟用該模式泼舱,但每一個(gè)HTTP/1.1-compliant代理和服務(wù)端都支持該模式等缀;
域分片 Domain sharding
注意:除非你有一個(gè)非常急迫的需求,不要使用這種技術(shù)娇昙,不如使用HTTP/2協(xié)議尺迂。在In HTTP/2中域分片更有效:HTTP/2的連接可以很好的處理并行請(qǐng)求,域分片甚至對(duì)性能是有害的冒掌。大部分的HTTP / 2的實(shí)現(xiàn)使用了一種叫做connection coalescing 的技術(shù)使用域分片噪裕。
在HTTP/1.x協(xié)議中,請(qǐng)求是串行化的股毫,甚至是無序的膳音,其性能很大程度上依賴于帶寬;為了解決這個(gè)問題铃诬,瀏覽器為每個(gè)域名打開幾個(gè)連接祭陷,發(fā)送并行的請(qǐng)求。默認(rèn)情況下一次是2到3個(gè)連接趣席,但是現(xiàn)在增加到了6個(gè)并行的連接兵志。如果超過這個(gè)數(shù)字,就會(huì)觸發(fā)服務(wù)端對(duì)DoS防御保護(hù)宣肚;
為了提升網(wǎng)站的性能想罕,服務(wù)器有可能強(qiáng)制打開更多連接. 比如分離出多個(gè)域名, www1.example.com
, www2.example.com
, www3.example.com
霉涨,而不是將所有資源都放在一個(gè)域名下www.example.com
按价;每個(gè)域名解析同一個(gè)服務(wù)器,然后瀏覽器為每個(gè)域名打開6個(gè)連接(在我們的例子中笙瑟,將連接數(shù)提升到了18)楼镐。這種技術(shù)就叫做域分片。