上文描述了在出現大量fin-wait-1出現的原因,占用的內存等,這里講一下如何處理這種情況。
首先,fin發送之后,有可能會丟棄,那么發送多少次這樣的fin包呢?fin包的重傳,也會采用退避方式,在2.6.358內核中采用的是指數退避,2s,4s,最后的
重試次數是由tcp_orphan_retries來限制的。
[root@localhost ~]# cat /proc/sys/net/ipv4/tcp_orphan_retries
0
查看對應版本的內核:
處理的變量是sysctl_tcp_orphan_retries,
/* Calculate maximal number or retries on an orphaned socket. */
static int tcp_orphan_retries(struct sock *sk, int alive)
{
int retries = sysctl_tcp_orphan_retries; /* May be zero. */
/* We know from an ICMP that something is wrong. */
if (sk->sk_err_soft && !alive)
retries = 0;
/* However, if socket sent something recently, select some safe
* number of retries. 8 corresponds to >100 seconds with minimal
* RTO of 200msec. */
if (retries == 0 && alive)----------------------------雖然cat看到的值是0,但其實內核中采用的是8.
retries = 8;
return retries;
}
將這個值改小,我的環境設置為2.
同時,將孤兒socket的數量限制改小。
/proc/sys/net/ipv4/tcp_max_orphans 修改為 500.
修改之后,可以看到內存明顯占用釋放出來。
由於客戶端窗口經常為0,在服務器做一下限速,平穩發包,防止丟包重傳之后,引起服務器的軟中斷也會上升。