TCP keepalive 概述(譯)

什麼是 TCP keepalive

TCP keepalive 概念很簡單:當創建一個TCP鏈接時,會設置了一系列與該鏈接相關的定時器。其中有些定時器跟處理 keepalive 相關,在 keepalive 定時器倒計時變爲零時,會給鏈接的另外一方發送一個 keepalive 探針包(probe packet),包內沒有數據且設置了 ACK 標識。html

若是收到一個 keepalive 探針包的響應,說明鏈接是正常和有效的。TCP 能夠處理只有協議頭,但實際數據長度爲零的數據包。這種機制是有用的,假如其餘主機斷開了鏈接,你能夠及時注意到鏈接的斷開。網絡

若是 keepalive 探針沒有響應,那麼能夠認爲鏈接不是有效的,進而能夠採起正確的操做。tcp

TCP keepalive 的應用場景

KeepAlive 是非侵入性的,大多數狀況下開啓 keepalive 不會有其餘風險。須要注意的是,這樣作會帶來額外的網絡開銷,例如會影響到路由器和防火牆。.net

  • 檢測實際斷掉的鏈接
  • 維持客戶端與 NAT 間的活躍網絡包

檢測實際斷掉的鏈接

設想 A、B 兩端建有 TCP 鏈接:最開始是三次握手,A 發送 SYN 報文段給 B,B 響應 SYN/ACK 給 A,最後 A 發送 ACK 給 B。如今兩端處於 established 狀態,都在等待對方發送數據。若是此時 B 電源被拔掉,在沒有發送任何數據的通知 A 的狀況下,B 已經斷開了鏈接。A 已經作好了準備接收數據,但不知道 B 已經宕機。以後 B 恢復供電而且系統重啓,A 覺得跟 B 的鏈接仍是正常的。此時 A 試圖給 B 發送數據,B 會回覆 RST 包,這樣 A 才關閉這個鏈接。rest

Keepalive 機制可讓 A 端避免出現上述的狀況。實際上,若是鏈接雙方有網絡問題,keepalive 經過定時發送 keepalive 已經及時感知到鏈接斷開。code

_____                                                     _____
   |     |                                                   |     |
   |  A  |                                                   |  B  |
   |_____|                                                   |_____|
      ^                                                         ^
      |--->--->--->-------------- SYN -------------->--->--->---|
      |---<---<---<------------ SYN/ACK ------------<---<---<---|
      |--->--->--->-------------- ACK -------------->--->--->---|
      |                                                         |
      |                                       system crash ---> X
      |
      |                                     system restart ---> ^
      |                                                         |
      |--->--->--->-------------- PSH -------------->--->--->---|
      |---<---<---<-------------- RST --------------<---<---<---|
      |                                                         |

維持客戶端與 NAT 間的活躍網絡包

keepalive 另外一個用途是阻止因網絡鏈接不活躍(長時間沒有數據包)而致使的鏈接斷開。htm

不少網絡設備,尤爲是NAT路由器,因爲其硬件的限制(例如內存、CPU處理能力),沒法保持其上的全部鏈接,所以在必要的時候會在鏈接池中選擇一些不活躍的鏈接踢掉。典型作法是LRU,把最久沒有數據的鏈接給踢掉。經過使用 TCP KeepAlive 機制,可讓鏈接每隔一小段時間就產生一些 ACK 包,以下降被踢掉的風險,固然,這樣的代價是額外的網絡和 CPU 負擔。ip

_____           _____                                     _____
   |     |         |     |                                   |     |
   |  A  |         | NAT |                                   |  B  |
   |_____|         |_____|                                   |_____|
      ^               ^                                         ^
      |--->--->--->---|----------- SYN ------------->--->--->---|
      |---<---<---<---|--------- SYN/ACK -----------<---<---<---|
      |--->--->--->---|----------- ACK ------------->--->--->---|
      |               |                                         |
      |               | <--- connection deleted from table      |
      |               |                                         |
      |--->- PSH ->---| <--- invalid connection                 |
      |               |                                         |

Linux 系統中的 keepalive

Linux 中跟 keepalive 相關的三個參數:內存

  • tcp_keepalive_time
  • tcp_keepalive_intvl
  • tcp_keepalive_probes

tcp_keepalive_time
發送最後一個數據包(只包含 ACK 的包不認爲是數據包)和發送第一個 probe 包之間間隔的時間路由

tcp_keepalive_intvl
發送兩個 keepalive probe 包之間間隔多長

tcp_keepalive_probes
連續發幾個 probe 包不回覆才認爲鏈接斷了

默認值

# cat /proc/sys/net/ipv4/tcp_keepalive_time
7200

# cat /proc/sys/net/ipv4/tcp_keepalive_intvl
75

# cat /proc/sys/net/ipv4/tcp_keepalive_probes
9

HTTP Keep-Alive是什麼?如何工做?
TCP-Keepalive

相關文章
相關標籤/搜索