1. 程式人生 > >tcp短連線TIME_WAIT問題解決方法大全(5)——tcp_max_tw_buckets

tcp短連線TIME_WAIT問題解決方法大全(5)——tcp_max_tw_buckets

參考官方文件(http://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt),解釋如下:
tcp_max_tw_buckets - INTEGER
Maximal number of timewait sockets held by system simultaneously.
If this number is exceeded time-wait socket is immediately destroyed
and warning is printed. 
官方文件沒有說明預設值,通過幾個系統的簡單驗證,初步確定預設值是180000

通過原始碼檢視發現,這個選項比較簡單,其實現程式碼如下:

=====linux-2.6.37 net/ipv4/tcp_minisocks.c 269======
void tcp_time_wait(struct sock *sk, int state, int timeo)
{
struct inet_timewait_sock *tw = NULL;
const struct inet_connection_sock *icsk = inet_csk(sk);
const struct tcp_sock *tp = tcp_sk(sk);
int recycle_ok = 0;


if (tcp_death_row.sysctl_tw_recycle && tp->rx_opt.ts_recent_stamp)

recycle_ok = icsk->icsk_af_ops->remember_stamp(sk);


if (tcp_death_row.tw_count < tcp_death_row.sysctl_max_tw_buckets)
tw = inet_twsk_alloc(sk, state);


if (tw != NULL) {
//分配成功,進行TIME_WAIT狀態處理,此處略去很多程式碼
    else {
//分配失敗,不進行處理,只記錄日誌TCP: time wait bucket table overflow
/* Sorry, if we're out of memory, just CLOSE this

* socket up.  We've got bigger problems than
* non-graceful socket closings.
*/
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPTIMEWAITOVERFLOW);
}


tcp_update_metrics(sk);
tcp_done(sk);
}
實測結果驗證,配置為100,TIME_WAIT連線數就穩定在100,且不受組網和其它配置的影響。

官方手冊中有一段警告:
    This limit exists only to prevent
simple DoS attacks, you _must_ not lower the limit artificially,
but rather increase it (probably, after increasing installed memory),
if network conditions require more than default value.
基本意思是這個用於防止Dos攻擊,我們不應該人工減少,如果網路條件需要的話,反而應該增加。
但其實對於我們的區域網或者公司內網應用來說,這個風險並不大。