1. 程式人生 > >TCP的keepalive和應用層的heart

TCP的keepalive和應用層的heart

需求 還要 服務 可用 但是 http 空閑 變化 字節

從長鏈接說起

TCP是長鏈接的,也就是說連接建立後,及時數年沒有通信連接仍然存在。這樣做的好處是:免去了DNS解析的時間,連接建立等時間,大大加快了請求的速度,同時也有利於接受服務器的實時消息。但前提是連接可用。

TCP的keepalive機制

服務器為了探測對端是否還活著,於是每隔兩小時發送一個keepalive報文(攜帶一個字節的Data)。個人覺得保活機制也就是在局域網中用用,路由器表項每個幾分鐘老化一次,連接早就不存在了。

保活機制的缺點

1、網關設備由於保活問題,導致其連接表滿,無法新建連接(XX局網閘故障案例)或性能下降嚴重

2、當連接一端在發送保活探測報文時,中間網絡正好由於各種異常(如鏈路中斷、中間設備重啟等)而無法將該保活探測報文正確轉發至對端時,可能會導致探測的一方釋放本來正常的連接,但是這種可能情況發生的概率較小,另外,一般也可以增加保活探測報文發生的次數來減小這種情況發生的概率和影響。

應用層為何還要心跳報文

為什麽我們需要使用應用層心跳來做檢測,而不是直接使用 TCP 的特性呢?

我們知道 TCP 是一個基於連接的協議,其連接狀態是由一個狀態機進行維護,連接完畢後,雙方都會處於 established 狀態,這之後的狀態並不會主動進行變化。這意味著如果上層不進行任何調用,一直使 TCP 連接空閑,那麽這個連接雖然沒有任何數據,但仍是保持連接狀態,一天、一星期、甚至一個月,即使在這期間中間路由崩潰重啟無數次。舉個現實中經常遇到的栗子:當我們 ssh 到自己的 VPS 上,然後不小心踢掉網線,此時的網絡變化並不會被 TCP 檢測出,當我們重新插回網線,仍舊可以正常使用 ssh,同時此時並沒有發生任何 TCP 的重連。

有人會說 TCP 不是有 KeepAlive 機制麽,通過這個機制來實現不就可以了嗎?但是事實上,TCP KeepAlive 的機制其實並不適用於此。Keep Alive 機制開啟後,TCP 層將在定時時間到後發送相應的 KeepAlive 探針以確定連接可用性。一般時間為 7200 s(詳情請參見《TCP/IP詳解》中第23章),失敗後重試 10 次,每次超時時間 75 s。顯然默認值無法滿足我們的需求,而修改過設置後就可以滿足了嗎?答案仍舊是否定的。

因為 TCP KeepAlive 是用於檢測連接的死活,而心跳機制則附帶一個額外的功能:檢測通訊雙方的存活狀態。兩者聽起來似乎是一個意思,但實際上卻大相徑庭。

考慮一種情況,某臺服務器因為某些原因導致負載超高,CPU 100%,無法響應任何業務請求,但是使用 TCP 探針則仍舊能夠確定連接狀態,這就是典型的連接活著但業務提供方已死的狀態,對客戶端而言,這時的最好選擇就是斷線後重新連接其他服務器,而不是一直認為當前服務器是可用狀態,一直向當前服務器發送些必然會失敗的請求。

從上面我們可以知道,KeepAlive 並不適用於檢測雙方存活的場景,這種場景還得依賴於應用層的心跳。應用層心跳有著更大的靈活性,可以控制檢測時機,間隔和處理流程,甚至可以在心跳包上附帶額外信息。從這個角度而言,應用層的心跳的確是最佳實踐。

TCP的keepalive和應用層的heart