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