回到公司,打开邮箱,看了看昨天的报表,发现一些业务的成功率下降,随后肯定就是领导们一个个“什么原因”的回复 。翻查日志查看,一大堆的“java.net.socketexception打开文件过多”异常。而报出这个异常的是hessian框架,hessian用了类似RMI的技术实现,最终的“途径”还是走http。出现这个问题已经是第二次了,看来随着用户规模的上升,啥问题都会有,相当刺激,来一个杀一个。
文件打开过多是因为http用到了socket,而socket的限制又受到了OS的参数设计影响,问题一步步分析就自然看到解决方法了:设置系统的openfile参数。简单描述设置openfile这个参数和使其生效的步骤:
1、查询Java进程ID:
ps -ef | grep java
1003 22965 1 2 Nov20 ? 00:28:15 /usr/lib64/jvm/jre/bin/java......
2、统计进程打开文件数:
lsof -p 22965 | wc -l
456
3、查询当前文件打开数:
ulimit -a
open files (-n) 1024
默认是1024
4、修改当前文件打开数值:
修改/etc/security /limits.conf的soft nofile和hard nofile值。
用户|组 soft nofile 1024
用户|组 hard nofile 65536
5、查询/etc/pam.d/login,看有没有以下配置,没有就加上。
session required /lib/security/pam_limits.so
6、重新登录用户就OK
步骤就大概是以上这些,如果需要了解原理网上资料多得是。接下来普及一下OS文件打开的概念。
在unix、linux这样的操作系统下,打开一个进程,就会有对文件的操作,有文件的操作就需要记录操作文件的标识,这就是文件描述符。实际上,文件描述符是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。习惯上,标准输入(standard input)的文件描述符是 0,标准输出(standard output)是 1,标准错误(standard error)是 2。
相关文件描述符与进程之间的关系,可参考一下链接:
http://blog.csdn.net/guo__peng/article/details/1331199
后续(20141210):
经过实践和检查,上述文件打开书操作会失效,由于我们操作服务器都是用过securecrt远程操作的,而securecrt的远程是支持SSH(Secure Shell)协议的,而ssh是不能修改ulimit值的。
原因请参考此链接: