情景描述:
最近发现应用后端时不时的存在open too many files的日志错误
CLOSE_WAIT是被动关闭(关闭请求由另一端主动发起),如果出现CLOSE_WAIT状态
99%
意味着你的应用程序
bug导致。
原因分析:在应用的API与应用Master通信过程中,因为应用API程序中没有正常关闭socket连接,在API端机器上查询socket状态均处于CLOSE_WAIT中,导致JAVA进程打开的句柄数达到了系统配置的上限值(1024),最终造成 “Too many open files”,无法再与应用Master通信。
(图中server表示Master, client表示API,client端出现CLOSE_WAIT表示client被动关闭)
解决方法:
1、调大进程可打开的文件句柄数(原来1024调整到65535),作为一个应用服务1024个文件句柄数实在是太太寒暄了呢。
- 使用root 登陆,修改文件/etc/security/limits.conf
- vim /etc/security/limits.conf 添加
#<domain> <type> <item> <value>
* soft nofile 65535
* soft nofile 65535
* hard nofile 65535
注:xxx - nofile 65535
xxx 是一个用户,如果是想所有用户生效的话换成 * ,设置的数值与硬件配置有关,别设置太大了。
2、调整CLOSE_WAIT的时间(这一步可视自己情况而定)
- 修改方法:(暂时生效,重新启动服务器后,会还原成默认值)
sysctl -w net.ipv4.tcp_keepalive_time=600
sysctl -w net.ipv4.tcp_keepalive_probes=2
sysctl -w net.ipv4.tcp_keepalive_intvl=2
注意:Linux的内核参数调整的是否合理要注意观察,看业务高峰时候 效果如何 - 若做如上修改后,可起作用;则做如下修改以便永久生效。
vi /etc/sysctl.conf
若 配置文件中不存在如下信息,则添加:
net.ipv4.tcp_keepalive_time = 1800
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl = 15
编辑完 /etc/sysctl.conf,要重启network 才会生效
/etc/rc.d/init.d/network restart
然 后,执行sysctl命令使修改生效,基本上就算完成了。
3.前两步是不能解决根本问题,最重要的是要将修复程序中Bug。我们是使用Apache Commons下的
HttpClient时,在使用HttpClient过程中一定要注意http请求关闭的问题。这是在使用HttpClient时容易忽略的细节。具体请参见《HttpClient容易忽视的细节——连接关闭
》