1. 程式人生 > >Linux上的TIME_WAIT和tcp_fin_timeout

Linux上的TIME_WAIT和tcp_fin_timeout

當Linux伺服器的TIME_WAIT過多時,
通常會想到去修改引數降低TIME_WAIT時長,
以減少TIME_WAIT數量,但Linux並沒有提供這樣的介面,
除非重新編譯核心。

Linux預設的TIME_WAIT時長一般是60秒,
定義在核心的include/net/tcp.h檔案中:
#define TCP_TIMEWAIT_LEN (60*HZ)
/* how long to wait to destroy TIME-WAIT state,
 * about 60 seconds
 */
#define TCP_FIN_TIMEOUTTCP_TIMEWAIT_LEN
/* BSD style FIN_WAIT2 deadlock breaker.

 * It used to be 3min, new value is 60sec,
 * to combine FIN-WAIT-2 timeout with
 * TIME-WAIT timer.
 */

注意tcp_fin_timeout不是TIME_WAIT時間:
# cat /proc/sys/net/ipv4/tcp_fin_timeout
60
tcp_fin_timeout實為FIN_WAIT_2狀態的時長,
Linux沒有提供修改TIME_WAIT時長介面,除非修改巨集的定義重新編譯核心。
但Windows可以修改登錄檔中的TcpTimedWaitDelay值來控制TIME_WAIT時長。

RTO:超時重傳(Retransmission Timeout)


TIME_WAIT是一個常見經常的問題,相關內容(/etc/sysctl.conf或/proc/sys/net/ipv4):
1) net.ipv4.tcp_timestamps
   為1表示開啟TCP時間戳,用來計算往返時間RTT(Round-Trip Time)和防止序列號迴繞
2) net.ipv4.tcp_tw_reuse
   為1表示允許將TIME-WAIT的控制代碼重新用於新的TCP連線
3) net.ipv4.tcp_tw_recycle
   為1表示開啟TCP連線中TIME-WAIT的快速回收,NAT環境可能導致DROP掉SYN包(回覆RST)
4) net.ipv4.tcp_fin_timeout

   FIN_WAIT_2狀態的超時時長
5) net.ipv4.tcp_syncookies
   為1時SYN Cookies,當SYN等待佇列溢位時啟用cookies來處理,可防範少量SYN攻擊
6) net.ipv4.tcp_max_tw_buckets
   保持TIME_WAIT套接字的最大個數,超過這個數字TIME_WAIT套接字將立刻被清除並列印警告資訊
7) net.ipv4.ip_local_port_range
8) net.ipv4.tcp_max_syn_backlog
   埠最大backlog核心限制,防止佔用過大核心記憶體
9) net.ipv4.tcp_syn_retries
   對一個新建連線,核心要傳送多少個SYN連線請求才決定放棄,不應該大於255
10) net.ipv4.tcp_retries1
   放棄迴應一個TCP連線請求前﹐需要進行多少次重試,RFC規定最低的數值是3,這也是預設值
11) net.ipv4.tcp_retries2
   在丟棄啟用(已建立通訊狀況)的TCP連線之前﹐需要進行多少次重試,預設值為15
12) net.ipv4.tcp_synack_retries
   TCP三次握手的SYN/ACK階段重試次數,預設5

13) net.ipv4.tcp_max_orphans
   不屬於任何程序(已經從程序上下文中刪除)的sockets最大個數,超過這個值會被立即RESET,並同時顯示警告資訊
14) net.ipv4.tcp_orphan_retries
   孤兒sockets廢棄前重試的次數,預設值是7
15) net.ipv4.tcp_mem
   核心分配給TCP連線的記憶體,單位是page:
   第一個數字表示TCP使用的page少於此值時,核心不進行任何處理(干預),
   第二個數字表示TCP使用的page超過此值時,核心進入“memory pressure”壓力模式,
   第三個數字表示TCP使用的page超過些值時,報“Out of socket memory”錯誤,TCP 連線將被拒絕
16) net.ipv4.tcp_rmem
   為每個TCP連線分配的讀緩衝區記憶體大小,單位是byte
17) net.ipv4.tcp_wmem
   為每個TCP連線分配的寫緩衝區記憶體大小,單位是byte:
   第一個數字表示,為TCP連線分配的最小記憶體,
   第二個數字表示,為TCP連線分配的預設記憶體,
   第三個數字表示,為TCP連線分配的最大記憶體(net.core.wmem_max可覆蓋該值)
18) net.ipv4.tcp_keepalive_time
   當keepalive起用的時候,TCP傳送keepalive訊息的頻度,單位為秒,預設是7200秒(即2小時)
19) net.ipv4.tcp_keepalive_intvl
   keepalive探測包的傳送間隔    
20) net.ipv4.tcp_keepalive_probes
   如果對方不予應答,探測包的傳送次數

程式碼中可通過SO_LINGER來控制。