1. 程式人生 > 其它 >TCP連結keepalive機制介紹

TCP連結keepalive機制介紹

什麼是KeepAlive

KeepAlive可以簡單理解為一種狀態保持或重用機制,比如當一條連線建立後,我們不想它立刻被關閉,如果實現了KeepAlive機制,就可以通過它來實現連線的保持。
簡單的說就是當你跟女朋友打電話但是沒話講,又不能掛的時候,每隔固定週期喊一聲“餵你還在嗎”的機制。

TCP為什麼要做KeepAlive

  1. 我們都知道TCP的三次握手和四次揮手。當兩端通過三次握手建立TCP連線後,就可以傳輸資料了,資料傳輸完畢,連線並不會自動關閉,而是一直保持。只有兩端分別通過傳送各自的 FIN 報文時,才會關閉自己側的連線。
  2. 這個關閉機制看起來簡單明瞭,但實際網路環境千變萬化,衍生出了各種問題。假設因為實現缺陷、突然崩潰、惡意攻擊或網路丟包等原因,一方一直沒有傳送 FIN 報文,則連線會一直保持並消耗著資源,為了防止這種情況,一般接收方都會主動中斷一段時間沒有資料傳輸的TCP連線,比如LVS會預設中斷90秒內沒有資料傳輸的TCP連線,F5會中斷5分鐘內沒有資料傳輸的TCP連線
  3. 但有的時候我們的確不希望中斷空閒的TCP連線,因為建立一次TCP連線需要經過一到兩次的網路互動,且由於TCP的 slow start 機制,新的TCP連線開始資料傳輸速度是比較慢的,我們希望通過連線池模式,保持一部分空閒連線,當需要傳輸資料時,可以從連線池中直接拿一個空閒的TCP連線來全速使用,這樣對效能有很大提升
  4. 為了支援這種情況,TCP實現了KeepAlive機制。KeepAlive機制並不是TCP規範的一部分,但無論Linux和Windows都實現實現了該機制。TCP實現裡KeepAlive預設都是關閉的,且是每個連線單獨設定的,而不是全域性設定

Implementors MAY include "keep-alives" in their TCP implementations, although this practice is not universally accepted. If keep-alives are included, the application MUST be able to turn them on or off for each TCP connection, and they MUST default to off.

另外有一個特殊情況就是,當某應用程序關閉後,如果還有該程序相關的TCP連線,一般來說作業系統會自動關閉這些連線

如何檢視TCP的keepalive引數配置

Linux中KeepAlive相關的配置可以通過如下方式檢視

cat /proc/sys/net/ipv4/tcp_keepalive_time
cat /proc/sys/net/ipv4/tcp_keepalive_intvl
cat /proc/sys/net/ipv4/tcp_keepalive_probes

在Linux中我們可以通過修改核心引數 /etc/sysctl.conf 的全域性配置:

net.ipv4.tcp_keepalive_time=7200
net.ipv4.tcp_keepalive_intvl=75
net.ipv4.tcp_keepalive_probes=9

新增上面的配置後輸入 sysctl -p 使其生效,你可以使用 sysctl -a | grep keepalive 命令來檢視當前的預設配置

如果應用中已經設定SO_KEEPALIVE,程式不用重啟,核心直接生效

如何監測TCP連線的keepalive狀態

ss -aoen|grep ESTAB

觀察結果中的timer,為程式中定義的keepalive定時器,持續執行可以看到時間縮小後再次計時。