keepalive可以簡單理解為一種狀態保持或重用機制,比如當一條連線建立後,我們不想它立刻被關閉,如果實現了keepalive機制,就可以通過它來實現連線的保持。
簡單的說就是當你打**但是沒話講,又不能掛的時候,每隔固定週期喊一聲「喂你還在嗎」的機制。
我們都知道tcp的三次握手和四次揮手。當兩端通過三次握手建立tcp連線後,就可以傳輸資料了,資料傳輸完畢,連線並不會自動關閉,而是一直保持。只有兩端分別通過傳送各自的 fin 報文時,才會關閉自己側的連線。
這個關閉機制看起來簡單明瞭,但實際網路環境千變萬化,衍生出了各種問題。假設因為實現缺陷、突然崩潰、惡意攻擊或網路丟包等原因,一方一直沒有傳送 fin 報文,則連線會一直保持並消耗著資源,為了防止這種情況,一般接收方都會主動中斷一段時間沒有資料傳輸的tcp連線,比如lvs會預設中斷90秒內沒有資料傳輸的tcp連線,f5會中斷5分鐘內沒有資料傳輸的tcp連線
但有的時候我們的確不希望中斷空閒的tcp連線,因為建立一次tcp連線需要經過一到兩次的網路互動,且由於tcp的 slow start 機制,新的tcp連線開始資料傳輸速度是比較慢的,我們希望通過連線池模式,保持一部分空閒連線,當需要傳輸資料時,可以從連線池中直接拿乙個空閒的tcp連線來全速使用,這樣對效能有很大提公升
為了支援這種情況,tcp實現了keepalive機制。keepalive機制並不是tcp規範的一部分,但無論linux和windows都實現實現了該機制。tcp實現裡keepalive預設都是關閉的,且是每個連線單獨設定的,而不是全域性設定
另外有乙個特殊情況就是,當某應用程序關閉後,如果還有該程序相關的tcp連線,一般來說作業系統會自動關閉這些連線
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,程式不用重啟,核心直接生效ss -aoen|grep estab
觀察結果中的timer,為程式中定義的keepalive定時器,持續執行可以看到時間縮小後再次計時。
對TCP選項keepalive使用的疑問
我設計的伺服器加入了keepalive選項的支援,這個保活機制在內網環境測試是ok的。前兩天在生產環境,出現了有幾個連線的保活沒起作用的情況,client機器重啟後,server端的socket一直沒有斷開,現在懷疑是和keepalive設定的值有關,以下是我的設定 net.ipv4.tcp kee...
TCP三次握手和keep alive
tcp ip協議很久之前看過,現在忘得差不多了,補充一下tcp的三次握手和狀態。img 當對已經關閉的tcp套接字呼叫recv時,會返回 1,表示連線已經關閉,這是因為tcp有乙個keep alive的機制,相當於心跳連線,保證連線斷開時,或者對方異常關閉時,自己能夠馬上知道,不會導致在recv上堵...
TCP長鏈結和短鏈結
tcp在真正的讀寫操作之前,server與client之間必須建立乙個連線,當讀寫操作完成後,雙方不再需要這個連線時它們可以釋放這個連線,連線的建立通過三次握手,釋放則需要四次握手,所以說每個連線的建立都是需要資源消耗和時間消耗的。tcp通訊的整個過程,如下圖 模擬一種tcp短連線的情況 1.cli...