vi /etc/sysctl.conf,加入以下内容:
net.ipv4.tcp_tw_reuse=1 #表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭
net.ipv4.tcp_tw_recycle=1 #表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭
net.ipv4.tcp_fin_timeout=30 #修改系統默认的TIMEWAIT时间
net.ipv4.tcp_max_tw_buckets=3000 #限制TIMEWAIT的数量
net.ipv4.tcp_timestamps=1 #启用TCP的时间戳选项
net.ipv4.ip_local_port_range=1024 65000 #这表明将系统对本地端口范围限制设置为1024~65000之间。请注意,本地端口范围的最小值必须大于或等于1024;而端口范围的最大值则应小于或等 于65535
然后执行 /sbin/sysctl -p 让参数生效。
实验的结论:
1.主动连接情况下,TIME_WAIT对性能的影响很大
2.net.ipv4.tcp_tw_reuse和tcp_tw_recycle都设置为0时,在本地端口耗尽后负载会很高
3.net.ipv4.tcp_tw_reuse=1和net.ipv4.tcp_tw_recycle=1 配置生效的前提条件是:TCP连接的两端都要启用TCP的时间戳选项, net.ipv4.tcp_timestamps=1。
4.net.ipv4.tcp_tw_reuse设置为1后,会降低本地端口耗尽出现的概率,从而降低负载
5.net.ipv4.tcp_tw_recycle设置为1后,会加速TIME_WAIT的回收,从而显著降低系统中TIME_WAIT状态的socket数量
6.对于主动连接较多的服务器建议通过调整sysctl的net.ipv4.ip_local_port_range来增大本地端口范围,以进一步降低端口耗尽出现的概率
除此之外,对于高并发的网络应用,还应注意以下一些点:
1。ulimit -n #看一下一个进程可以打开的文件句柄数目,如果要修改系统默认的hard nofile阈值,需要按照以下步骤进行:
第一步,修改/etc/security/limits.conf文件,在文件中添加如下行:
admin soft nofile 10240
admin hard nofile 10240
其中admin指定了要修改哪个用户的打开文件数限制,可用'*'号表示修改所有用户的限制;soft或hard指定要修改软限制还是硬限制;10240 则指定了想要修改的新的限制值,即最大打开文件数(请注意软限制值要小于或等于硬限制)。修改完后保存文件。
第二步,修改/etc/pam.d/login文件,在文件中添加如下行:
session required /lib/security/pam_limits.so
这是告诉Linux在用户完成系统登录后,应该调用pam_limits.so模块来设置系统对该用户可使用的各种资源数量的最大限制(包括用户可打开的 最大文件数限制),而pam_limits.so模块就会从/etc/security/limits.conf文件中读取配置来设置这些限制值。修改完 后保存此文件。
2。cat /proc/sys/fs/file-max #这表明这台Linux系统最多允许同时打开(即包含所有用户打开文件数总和)XXXX个文件,是Linux系统级硬限制,不够时将其调大
3。还有一种无法建立TCP连接的原因可能是因为Linux网络内核的IP_TABLE防火墙对最大跟踪的TCP连接数有限制。此时程序会表现为在 connect()调用中阻塞,如同死机,如果用tcpdump工具监视网络,也会发现根本没有TCP连接时客户端发SYN包的网络流量。由于 IP_TABLE防火墙在内核中会对每个TCP连接的状态进行跟踪,跟踪信息将会放在位于内核内存中的conntrackdatabase中,这个数据库 的大小有限,当系统中存在过多的TCP连接时,数据库容量不足,IP_TABLE无法为新的TCP连接建立跟踪信息,于是表现为在connect()调用 中阻塞。此时就必须修改内核对最大跟踪的TCP连接数的限制,方法同修改内核对本地端口号范围的限制是类似的:在/etc/sysctl.conf中添加net.ipv4.ip_conntrack_max=10240
参考文章:
http://hi.baidu.com/zzxap/blog/item/ab3f2aedbe6c3b5978f05587.html《Linux下突破限制实现高并发量服务器》
http://kerry.blog.51cto.com/172631/105233/《发现大量的TIME_WAIT解决办法》
http://wenku.baidu.com/view/dd18767c1711cc7931b71616.html《操作系统性能优化<1> Linux下TIME_WAIT对系统性能的影响》
http://blog.csdn.net/kasagawa/article/details/6978890《TCP协议学习笔记》
今天又遇到了CLOSE_WAIT的情况,google了一番,又对TIME_WAIT和CLOSE_WAIT的理解深了一层,参考的几篇文章如下:
http://www.360doc.com/content/10/0414/16/1484_23029426.shtml
http://pengtyao.iteye.com/blog/829513
http://shootyou.iteye.com/blog/1129507
http://blog.csdn.net/shootyou/article/details/6615051
http://hi.baidu.com/tantea/blog/item/580b9d0218f981793812bb7b.html
大致说一下我的一些新的理解:
TCP建立连接需要3次握手(就是发3个包),而终止连接需要发4个包(两次FIN,两次ACK),在终止的时候,调用close会触发发送FIN包,通常我们说客户端和服务器,但这都是相对而言的,更准确的说法是“主动关闭方”和“被动关闭方”,主动关闭方会出现TIME_WAIT(出现在对方也调用了close之后,在对方调用close之前是FIN_WAIT2状态),被动关闭方会出现CLOSE_WAIT(出现在收到对方关闭请求但自己又没有调用close之前);主动关闭方的TIME_WAIT的等待是正常的,tcp/ip协议就是这么设计的,可以通过调整机器的内核参数来控制,被动关闭方的CLOSE_WAIT的等待是应用程序自己造成的,和系统没有关系,通常是被动关闭方没有调用close导致的;TIME_WAIT出现后,需要等待2个MSL时间才会释放socket,CLOSE_WAIT出现后需要等待一个keepalive的时间,关于keepalive的控制主要有3个参数:net.ipv4.tcp_keepalive_intvl(每次探测间隔)、net.ipv4.tcp_keepalive_probes(探测次数)、net.ipv4.tcp_keepalive_time(TCP链路上空闲多长时间开始发送keep_alive),tcp_keepalive_time默认为2小时,因此CLOSE_WAIT后最多有可能需要等待tcp_keepalive_time + tcp_keepalive_intvl * tcp_keepalive_probes;此外,不论是主动方还是被动方,只要程序退出(因为程序退出会关闭所有打开的fd),则相当于调用了close函数,那么对于被动方而言CLOSE_WAIT都会消失,对于主动方而言,退出前保持的FIN_WAIT2或TIME_WAIT状态继续保留;如果双方都主动退出程序,那么谁先退出就相当于是优先调用了close的主动方。
https://www.byvoid.com/blog/http-keep-alive-header
http://www.jellythink.com/archives/705
http://www.jellythink.com/archives/705