应用“open too many files"有关问题调查

应用“open too many files"问题调查
情景描述最近发现应用后端时不时的存在open too many files的日志错误

原因分析在应用的API与应用Master通信过程中,因为应用API程序中没有正常关闭socket连接,在API端机器上查询socket状态均处于CLOSE_WAIT中,导致JAVA进程打开的句柄数达到了系统配置的上限值(1024),最终造成 “Too many open files”,无法再与应用Master通信。 
应用“open too many files"有关问题调查
CLOSE_WAIT是被动关闭(关闭请求由另一端主动发起),如果出现CLOSE_WAIT状态99%意味着你的应用程序 bug导致。

应用“open too many files"有关问题调查
(图中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
    *             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容易忽视的细节——连接关闭