【网络协议】TCP和HTTP中keep alive机制
簡介:TCP協(xié)議和HTTP協(xié)議中,都有keepalive機(jī)制,只是二者的含義有所不同。TCP中keepalive主要用來進(jìn)行鏈路檢測;HTTP中keepalive主要用來進(jìn)行鏈路復(fù)用。其中http1.1版本已經(jīng)默認(rèn)支持keepalive,即支持持久連接。下面將詳細(xì)分析TCP和HTTP中keepalive機(jī)制。
1、TCP keep alive
(1)
??? TCP是無感知的虛擬連接,中間斷開兩端不會(huì)立刻得到通知。一般在使用長連接的環(huán)境下,需要心跳保活機(jī)制可以勉強(qiáng)感知其存活。業(yè)務(wù)層面有心跳機(jī)制,TCP協(xié)議也提供了心跳保活機(jī)制。
??? 長連接的環(huán)境下,一旦有熱數(shù)據(jù)需要傳遞,若此時(shí)連接已經(jīng)被中介設(shè)備斷開,應(yīng)用程序沒有及時(shí)感知的話,那么就會(huì)導(dǎo)致在一個(gè)無效的數(shù)據(jù)鏈路層面發(fā)送業(yè)務(wù)數(shù)據(jù),結(jié)果就是發(fā)送失敗。
無論是因?yàn)榭蛻舳艘馔鈹嚯姟⑺罊C(jī)、崩潰、重啟,還是中間路由網(wǎng)絡(luò)無故斷開、NAT超時(shí)等,服務(wù)器端要做到快速感知失敗,減少無效鏈接操作。
(2)
在一個(gè)正常的TCP連接上,當(dāng)我們用無限等待的方式調(diào)用下面的recv或send的時(shí)候:
ret=recv(s);或ret=send(s);如果TCP連接被對方正常關(guān)閉,也就是說,對方是正確地調(diào)用了closesocket(s)或者shutdown(s)的話,那么上面的recv或send調(diào)用就能馬上返回,并且報(bào)錯(cuò)。這是由于closesocket()或者shutdown()有個(gè)正常的關(guān)閉過程,會(huì)告訴對方“TCP連接已經(jīng)關(guān)閉,你不需要再發(fā)送或者接受消息了”。但是,如果是網(wǎng)線突然被拔掉,TCP連接的任何一端的機(jī)器突然斷電或重啟動(dòng),那么這時(shí)候正在執(zhí)行recv或send操作的一方就會(huì)因?yàn)闆]有任何連接中斷的通知而一直等待下去,也就是會(huì)被長時(shí)間卡住。這種情形解決的辦法是啟動(dòng)TCP編程里的keepAlive機(jī)制。
keepaliveinterval=5000; //單位為毫秒
keepalivetime=1000;???? //單位為毫秒
此處的keepalivetime表示的是TCP連接處于暢通時(shí)候的探測頻率,一旦探測包沒有返回,就以keepaliveinterval的頻率發(fā)送,經(jīng)過若干次的重試,如果探測包都沒有返回,那么就得出結(jié)論:TCP連接已經(jīng)斷開,于是上面的recv或send調(diào)用也就能馬上返回,不會(huì)無限制地卡住了。
(3)
keepalive三個(gè)參數(shù):
sk->keepalive_probes:探測次數(shù)
sk->keepalive_time?? 探測的超時(shí)
sk->keepalive_intvl 探測間隔
對 于一個(gè)已經(jīng)建立的tcp連接。如果在keepalive_time時(shí)間內(nèi)雙方?jīng)]有任何的數(shù)據(jù)包傳輸,則開啟keepalive功能的一端將發(fā)送 keepalive數(shù)據(jù)包,若沒有收到應(yīng)答,則每隔keepalive_intvl時(shí)間再發(fā)送該數(shù)據(jù)包,發(fā)送keepalive_probes次。一直沒有 收到應(yīng)答,則發(fā)送rst包關(guān)閉連接。若收到應(yīng)答,則將計(jì)時(shí)器清零。
sk->keepalive_probes = 3;
sk->keepalive_time?? = 30;
sk->keepalive_intvl = 1;
意 思就是說對于tcp連接,如果一直在socket上有數(shù)據(jù)來往就不會(huì)觸發(fā)keepalive,但是如果30秒一直沒有數(shù)據(jù)往來,則keep alive開始工作:發(fā)送探測包,收到響應(yīng)則認(rèn)為網(wǎng)絡(luò),是好的,結(jié)束探測;如果沒有響應(yīng),就每隔1秒發(fā)探測包,一共發(fā)送3次,3次后仍沒有響應(yīng),則發(fā)送RST包關(guān)閉連接,也就是從網(wǎng)絡(luò)開始到你的socket能夠意識(shí)到網(wǎng)絡(luò)異常,最多花33秒。但是如果沒有設(shè)置keep alive,可能你在你的socket(阻塞性)的上面,接收: recv會(huì)一直阻塞不能返回,除非對端主動(dòng)關(guān)閉連接,因?yàn)閞ecv不知道socket斷了。
我們知道TCP連接關(guān)閉時(shí),需要連接的兩端中的某一方發(fā)起關(guān)閉動(dòng)作,如果某一方突然斷電,另外一端是無法知道的。tcp的keep_alive就是用以檢測異常的一種機(jī)制。
但是,tcp自己的keepalive有這樣的一個(gè)bug:正常情況下,連接的另一端主動(dòng)調(diào)用colse關(guān)閉連接,tcp會(huì)通知,我們知道了該連接已經(jīng)關(guān)閉。但是如果tcp連接的另一端突然掉線,或者重啟斷電,這個(gè)時(shí)候我們并不知道網(wǎng)絡(luò)已經(jīng)關(guān)閉。而此時(shí),如果有發(fā)送數(shù)據(jù)失敗,tcp會(huì)自動(dòng)進(jìn)行重傳。重傳包的優(yōu)先級(jí)高于keepalive,那就意味著,我們的keepalive總是不能發(fā)送出去。 而此時(shí),我們也并不知道該連接已經(jīng)出錯(cuò)而中斷。在較長時(shí)間的重傳失敗之后,我們才會(huì)知道。
2、HTTP keep alive
在http早期,每個(gè)http請求都要求打開一個(gè)tcp socket連接,并且使用一次之后就斷開這個(gè)tcp連接。
使用keep-alive可以改善這種狀態(tài),即在一次TCP連接中可以持續(xù)發(fā)送多份數(shù)據(jù)而不會(huì)斷開連接。通過使用keep-alive機(jī)制,可以減少tcp連接建立次數(shù),也意味著可以減少TIME_WAIT狀態(tài)連接,以此提高性能和提高h(yuǎn)ttpd服務(wù)器的吞吐率(更少的tcp連接意味著更少的系統(tǒng)內(nèi)核調(diào)用,socket的accept()和close()調(diào)用)。
但是,keep-alive并不是免費(fèi)的午餐,長時(shí)間的tcp連接容易導(dǎo)致系統(tǒng)資源無效占用。配置不當(dāng)?shù)膋eep-alive,有時(shí)比重復(fù)利用連接帶來的損失還更大。所以,正確地設(shè)置keep-alive timeout時(shí)間非常重要。
http keep-alive與tcp keep-alive,不是同一回事,意圖不一樣。http keep-alive是為了讓tcp活得更久一點(diǎn),以便在同一個(gè)連接上傳送多個(gè)http,提高socket的效率。而tcp keep-alive是TCP的一種檢測TCP連接狀況的保鮮機(jī)制。
3、TCP和HTTP的Keep-Alive總結(jié):
HTTP協(xié)議的Keep-Alive意圖在于連接復(fù)用,同一個(gè)連接上串行方式傳遞請求-響應(yīng)數(shù)據(jù)。
TCP的keepalive機(jī)制意圖在于保活、心跳,檢測連接錯(cuò)誤。
總結(jié)
以上是生活随笔為你收集整理的【网络协议】TCP和HTTP中keep alive机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 推销自己的最佳媒介之一就是博客
- 下一篇: 敏捷DoD和DoR的多种形态