ios http长连接_Nginx篇05——http长连接和keeplive
nginx中http模塊使用http長連接的相關(guān)配置(主要是keepalive指令)和http長連接的原理解釋。
1、http長連接
1.1 預(yù)備知識(shí)
連接管理是一個(gè) HTTP 的關(guān)鍵話題:打開和保持連接在很大程度上影響著網(wǎng)站和 Web 應(yīng)用程序的性能。在 HTTP/1.x 里有多種模型:短連接, 長連接, 和 HTTP 流水線。在解釋這三種模型之前,我們需要先明確一些前提知識(shí):
?HTTP是屬于應(yīng)用層(七層)的協(xié)議,同時(shí)它的傳輸層(四層)使用的是TCP協(xié)議,那么也就是說,HTTP的長連接和短連接,其本質(zhì)就是TCP的長連接和短連接;?HTTP是一個(gè)無狀態(tài)的面向連接的協(xié)議(使用TCP,面向連接、可靠傳輸),指的是協(xié)議對于事務(wù)處理沒有記憶能力,服務(wù)器不知道客戶端是什么狀態(tài),無狀態(tài)不代表HTTP不能保持TCP連接,更不能代表HTTP使用的是UDP協(xié)議(無連接);?TCP建立連接和斷開連接是需要三握四揮的,由于這個(gè)屬于計(jì)算機(jī)網(wǎng)絡(luò)基本知識(shí),所以原理這里不再贅述;
接下來我們開始解釋。
1.2 HTTP短連接模型
在早期,HTTP 使用一個(gè)簡單的模型來處理這樣的連接。這些連接的生命周期是短暫的:每發(fā)起一個(gè)請求時(shí)都會(huì)創(chuàng)建一個(gè)新的連接,并在收到應(yīng)答時(shí)立即關(guān)閉。這就是類似上面說的三次握手,在互聯(lián)網(wǎng)發(fā)展的早期一個(gè)網(wǎng)頁的資源并沒有現(xiàn)在這么多,很多可能只是一個(gè)簡單的靜態(tài)頁面而已,所以這樣的模型顯然很OK。客戶端獲取完所需資源之后,就斷開連接,不再占用服務(wù)器的資源。
套用TCP連接的三握四揮的模型來舉例:
三次握手:
A→B:今晚下班一起吃飯嗎?
B→A:好的,今晚下班一起吃飯。
A→B:好的,我知道你答應(yīng)我今晚下班一起吃飯的邀請了。
然后開始去吃飯,吃完飯到了兩個(gè)人需要各自回家的時(shí)候:
四次揮手:
A→B:我吃完飯準(zhǔn)備走了
B→A:等一下,我快吃完了
B→A:好了,我吃完了可以走了
A→B:好的,我知道你吃完了我們可以走了
然后兩人吃完飯就各回各家了
HTTP 短連接模型是最早期的模型,也是 HTTP/1.0 的默認(rèn)模型。每一個(gè) HTTP 請求都由它自己獨(dú)立的連接完成;這意味著發(fā)起每一個(gè) HTTP 請求之前都會(huì)有一次 TCP 握手,而且是連續(xù)不斷的。實(shí)際上,TCP 協(xié)議握手本身就是耗費(fèi)時(shí)間的,所以 TCP 可以保持更多的熱連接來適應(yīng)負(fù)載。短連接破壞了 TCP 具備的能力,新的冷連接降低了其性能。
在 HTTP/1.0 中如果沒有指定?Connection協(xié)議頭,或者是值被設(shè)置為?close就會(huì)啟用短連接模型,要在 HTTP/1.0 中啟用長連接模型,需要在協(xié)議頭中指定Connection: Keep-Alive?,不過并不建議這樣操作。
而在 HTTP/1.1 中,默認(rèn)使用長連接模型,只有當(dāng)?Connection被設(shè)置為?close?時(shí)才會(huì)用到這個(gè)短連接模型,協(xié)議頭都不用再去聲明它(但是一般還是會(huì)把它加上,以防萬一因?yàn)槟撤N原因要退回到 HTTP/1.0 )。
1.3 HTTP長連接模型
后來,網(wǎng)頁需要請求的資源越來越多,短連接模型顯然已經(jīng)十分吃力了。因?yàn)槎踢B接有兩個(gè)比較大的問題:創(chuàng)建新連接耗費(fèi)的時(shí)間尤為明顯(三次握手很耗費(fèi)時(shí)間),另外 TCP 連接的性能只有在該連接被使用一段時(shí)間后(熱連接)才能得到改善。因此在HTTP/1.1中引入了長連接模型和流水線模型。
在 HTTP/1.1 之前,長連接也被稱為keep-alive 連接。
一個(gè)長連接會(huì)保持一段時(shí)間,重復(fù)用于發(fā)送一系列請求,節(jié)省了新建 TCP 連接握手的時(shí)間,還可以利用 TCP 的性能增強(qiáng)能力。當(dāng)然這個(gè)連接也不會(huì)一直保留著:連接在空閑一段時(shí)間后會(huì)被關(guān)閉(服務(wù)器可以使用 Keep-Alive 協(xié)議頭來指定一個(gè)最小的連接保持時(shí)間)。
套用上面的例子來進(jìn)一步解釋:
三次握手:
A→B:今晚下班一起吃飯嗎?
B→A:好的,今晚下班一起吃飯。
A→B:好的,我知道你答應(yīng)我今晚下班一起吃飯的邀請了。
然后開始去吃飯,但是這時(shí)吃完飯就不是馬上四次揮手?jǐn)嚅_連接,AB兩人還順便去逛街、看電影(相當(dāng)于省去了三次握手使用已建立的連接來傳輸多個(gè)資源)
此處省略四次揮手
最后兩人就各回各家了
長連接也還是有缺點(diǎn)的;也就是前面提到的資源占用問題,就算是在空閑狀態(tài),它還是會(huì)消耗服務(wù)器資源,也更容易被DDoS攻擊。本質(zhì)上長連接是因?yàn)椴粩嗟厝挝帐纸⑦B接消耗的資源要大于維持連接所需要的資源才使用的,如果服務(wù)器處于高負(fù)載時(shí)段或者被DDoS,可以使用非長連接,即盡快關(guān)閉那些空閑的連接,也能對性能有所提升。
1.4 HTTP流水線模型
流水線模型的實(shí)現(xiàn)要復(fù)雜很多,而已效果也并不是特別好,主要還要考慮到各種兼容性,所以默認(rèn)是不啟用這個(gè)流水線模型的,而在HTTP/2中,流水線已經(jīng)被更好的算法給代替,如multiplexing。
默認(rèn)情況下,HTTP 請求是按順序發(fā)出的。下一個(gè)請求只有在當(dāng)前請求收到應(yīng)答過后才會(huì)被發(fā)出。由于會(huì)受到網(wǎng)絡(luò)延遲和帶寬的限制,在下一個(gè)請求被發(fā)送到服務(wù)器之前,可能需要等待很長時(shí)間。流水線是在同一條長連接上發(fā)出連續(xù)的請求,而不用等待應(yīng)答返回。這樣可以避免連接延遲。理論上講,性能還會(huì)因?yàn)閮蓚€(gè) HTTP 請求有可能被打包到一個(gè) TCP 消息包中而得到提升。就算 HTTP 請求不斷的繼續(xù),尺寸會(huì)增加,但設(shè)置 TCP 的?MSS(Maximum Segment Size)?選項(xiàng),仍然足夠包含一系列簡單的請求。
并不是所有類型的 HTTP 請求都能用到流水線:只有?idempotent方式,比如?GET、HEAD、PUT和?DELETE能夠被安全的重試:因?yàn)橛泄收习l(fā)生時(shí),流水線的內(nèi)容要能被輕易的重試,即出現(xiàn)了問題重試的成本要盡可能低,否則還不如使用長連接模型。
正確的實(shí)現(xiàn)流水線是復(fù)雜的:傳輸中的資源大小,多少有效的?RTT?會(huì)被用到,還有有效帶寬,流水線帶來的改善有多大的影響范圍。不知道這些的話,重要的消息可能被延遲到不重要的消息后面。這個(gè)重要性的概念甚至?xí)葑優(yōu)橛绊懙巾撁娌季?#xff01;因此 HTTP 流水線在大多數(shù)情況下帶來的改善并不明顯。此外,流水線受制于 HOL 問題。
摘自wiki
隊(duì)頭阻塞(Head-of-line blocking或縮寫為HOL blocking)在計(jì)算機(jī)網(wǎng)絡(luò)[1]的范疇中是一種性能受限的現(xiàn)象。它的原因是一列的第一個(gè)數(shù)據(jù)包(隊(duì)頭)受阻而導(dǎo)致整列數(shù)據(jù)包受阻。例如它有可能在緩存式輸入的交換機(jī)中出現(xiàn),有可能因?yàn)閭鬏旐樞蝈e(cuò)亂而出現(xiàn),亦有可能在HTTP流水線中有多個(gè)請求的情況下出現(xiàn)。
我們還是使用上面的例子來進(jìn)行解釋,這次的握手請求就變了,A一次向B發(fā)出了三個(gè)請求:
三次握手:
A→B:今晚下班一起吃飯、逛街、看電影嗎?
B→A:好的,今晚下班一起吃飯、逛街、看電影。
A→B:好的,我知道你答應(yīng)我今晚下班一起吃飯、逛街、看電影的邀請了。
實(shí)際上這樣子是有很大的風(fēng)險(xiǎn)的
如果是按照長連接模型,A可以根據(jù)B在吃飯的時(shí)候的反應(yīng)來決定要不要繼續(xù)去逛街看電影,也就是如果傳輸完了一次數(shù)據(jù)之后還保持連接就繼續(xù)傳輸,萬一連接突然斷開或者是不穩(wěn)定,那可能就要重新建立連接。(萬一B在吃飯的時(shí)候吃的不開心不想繼續(xù)逛街看電影那就等下次再吃飯逛街看電影)
但是如果按照流水線模型,A一次發(fā)送三個(gè)請求,雖然發(fā)送請求的時(shí)候省事兒了(三次握手的時(shí)候TCP打包傳輸請求更省事),但是誰也不知道吃飯逛街看電影的過程中會(huì)發(fā)生什么意外,時(shí)間越長越不穩(wěn)定,而且還容易出現(xiàn)萬一B想減肥不想吃飯,只想逛街看電影的情況呢?(HOL問題)
最后這里補(bǔ)充一張圖片來對比三種模型之間的差別:
2、Nginx中的keepalive指令
當(dāng)我們配置Nginx作為代理服務(wù)器的時(shí)候,想要支持HTTP長連接,需要client到Nginx和Nginx到server都是長連接,因?yàn)榇藭r(shí)Nginx既是client的server也是server的client。
了解了上面的原理之后,Nginx中的keepalive指令我們就非常好理解了,相關(guān)的指令主要有三個(gè),我們逐個(gè)進(jìn)行解釋:
2.1?keepalive
Syntax: keepalive connections;Default: —
Context: upstream
This directive appeared in version 1.1.4.
在upstream模塊中配置,啟用連接到upstream中的服務(wù)器的緩存,connections參數(shù)的主要作用是設(shè)定每個(gè)Nginx的單個(gè)worker進(jìn)程(each worker process)對于upstream中的server的最大空閑連接數(shù),當(dāng)超過該數(shù)字的時(shí)候,會(huì)關(guān)閉使用得最少的連接。
?
對于HTTP,應(yīng)將proxy_http_version指令設(shè)置為“?1.1”,并且應(yīng)清除Connection標(biāo)題字段
?
對于FastCGI服務(wù)器,需要設(shè)置fastcgi_keep_conn以啟用keepalive連接
upstream http_backend {server 127.0.0.1:8080;
keepalive 16;
}
server {
location /http/ {
proxy_pass http://http_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
lcaotion /FastCGI/ {
fastcgi_pass fastcgi_backend;
fastcgi_keep_conn on;
}
}
需要注意的是,keepalive指令并不會(huì)限制Nginx的所有worker進(jìn)程能開啟的連接到upstream服務(wù)器中的連接總數(shù)(total number)。也就是如果設(shè)得太大了,會(huì)導(dǎo)致過多的空閑連接占滿了upstream中的server資源,導(dǎo)致新的連接無法建立,因此這個(gè)數(shù)值的設(shè)定需要根據(jù)worker進(jìn)程數(shù)量來調(diào)整。
2.2?keepalive_requests
Syntax: keepalive_requests number;Default: keepalive_requests 100;
Context: upstream
This directive appeared in version 1.15.3.
keepalive_requests設(shè)定可以通過一個(gè)連接(connection)發(fā)送的請求(request)數(shù)量,超過最大請求數(shù)量之后,該連接會(huì)被關(guān)閉。為了釋放每個(gè)連接的內(nèi)存分配,定期關(guān)閉連接是很有必要的。因此,不建議將keepalive_requests設(shè)定過大,否則可能會(huì)導(dǎo)致過高的內(nèi)存占用。
2.3?keepalive_timeout
Syntax: keepalive_timeout timeout;Default: keepalive_timeout 60s;
Context: upstream
This directive appeared in version 1.15.3.
設(shè)定連接超時(shí)時(shí)間,在此設(shè)定的時(shí)間內(nèi),client與upstream中的server的空閑keepalive連接將保持打開狀態(tài)(open)。此外,雖然官方文檔說的默認(rèn)值是60s,但是1.17.9版本的Nginx在安裝之后配置文件nginx.conf上面設(shè)定的是65s。
References
[1]?計(jì)算機(jī)網(wǎng)絡(luò):?https://zh.wikipedia.org/wiki/計(jì)算機(jī)網(wǎng)絡(luò)
總結(jié)
以上是生活随笔為你收集整理的ios http长连接_Nginx篇05——http长连接和keeplive的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: matlab在电力系统故障的应用,MAT
- 下一篇: linux下搜狗安装目录,Linux安装