上文描述了在出现大量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,在服务器做一下限速,平稳发包,防止丢包重传之后,引起服务器的软中断也会上升。