解决Linux下“java.net.SocketException: Too many open files”异常

背景: 

项目上线后发现Telnet模块在稳定运行一段时间后会自动断开,无法登陆,后台抛出:“java.net.SocketException: Too many open files”异常。 

环境: 

Java代码   收藏代码
  1. Linux版本:cat /proc/version  
  2.   
  3. Linux version 2.6.18-164.el5 (mockbuild@x86-003.build.bos.redhat.com) (gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)) #1 SMP Tue Aug 18 15:51:48 EDT 2009  
  4.   
  5. Weblogic:10.3  
  6. JDK:jrockit-jdk1.6.0_29-R28.2.2-4.1.0  



原因有以下两个: 

1、打开的Socket客户端并没有正常关闭,此处可能是自动超时功能有问题或者网络突然断开等。 

2、Linux默认设置的文件最大打开数太小(默认值:1024,使用:ulimit -n 命令查看)。 

基于以上两点,故从以下三个方面着手解决:1、操作系统Linux 2、应用服务器Weblogic 3、程序 

配置Linux文件最大打开数: 

Java代码   收藏代码
  1. /etc/security/limits.conf:在该文件的最后加入,最大文件打开数:  
  2.   
  3. * soft nofile 65535  
  4. * hard nofile 65535  
  5.   
  6. /etc/pam.d/login:在该文件的最后加入:  
  7.   
  8. session required /lib/security/pam_limits.so  
  9.   
  10. 重新登录后使用命令查看:ulimit -n,是否和设置保持一致  



3、修改Weblogic最大文件句柄数:(重启服务后生效) 

Java代码   收藏代码
  1. bea/wlserver_10.3/common/bin/commEnv.sh  
  2.   
  3. # limit the number of open file descriptors  
  4. resetFd() {  
  5.   if [ ! -n "`uname -s |grep -i cygwin || uname -s |grep -i windows_nt || \  
  6.        uname -s |grep -i HP-UX`" ]  
  7.   then  
  8.     ofiles=`ulimit -S -n`  
  9.     maxfiles=`ulimit -H -n`  
  10.     if [ "$?" = "0" -a  `expr ${maxfiles} : '[0-9][0-9]*$'` -eq 0 -a `expr ${ofiles} : '[0-9][0-9]*$'` -eq 0 ]; then     
  11.       ulimit -n 65535  
  12.     fi  
  13.   fi  
  14. }  

4、优化 Linux TCP 配置: 

Java代码   收藏代码
  1. /etc/sysctl.conf  
  2.   
  3. 2012-04-09 begin  
  4.   
  5. ## 允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;  
  6. net.ipv4.tcp_tw_reuse = 1  
  7.   
  8. ## 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭;  
  9. net.ipv4.tcp_tw_recycle = 1  
  10.   
  11. ##  修改系統默认的 TIMEOUT 时间  
  12. net.ipv4.tcp_fin_timeout = 30  
  13.   
  14. ## 表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时  
  15. net.ipv4.tcp_keepalive_time = 1800  
  16.   
  17. ## TCP发送keepalive探测以确定该连接已经断开的次数  
  18. net.ipv4.tcp_keepalive_probes = 5  
  19.   
  20. ## 探测消息发送的频率,乘以tcp_keepalive_probes就得到对于从开始探测以来没有响应的连接杀除的时间。  
  21. net.ipv4.tcp_keepalive_intvl = 15  
  22.   
  23. ## 表示SYN队列的长度,默认为1024,可以容纳更多等待连接的网络连接数  
  24. net.ipv4.tcp_max_syn_backlog = 4096  
  25.   
  26. ## 最大文件句柄数  
  27. fs.file-max=65535  
  28.   
  29. 2012-04-09 end  
  30.   
  31. # /sbin/sysctl -p 使上述配置生效命令  



5、Java Socket程序中,增加如下配置: 

Java代码   收藏代码
  1. socket.setTcpNoDelay(true); // 关闭Nagle算法, 立即发包  
  2. socket.setKeepAlive(true);  



6、常用Linux命令:(个人备忘) 

Java代码   收藏代码
  1. 1、查看进程:ps -ef|grep [java、tomcat、weblogic]  
  2. 2、查看某端口TCP连接占用数:netstat -pnt | grep :6666 |wc -l  
  3. 3、查看某端口TCP连接占用信息:lsof -i :6666  
  4. 4、查看TCP连接状态以及数量:netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'  
  5. 5、查看所有进程占用的文件句柄数:lsof -n|awk '{print $2}'|sort|uniq -c |sort -nr|more  
  6. 6、查看某进程所属服务:ps -aef|grep 24204  



9、优化结果 
总共83把手持设备,现在24小时作业每天的TCP连接数保持在:70左右。以前一到600多系统就宕机了。

猜你喜欢

转载自hroke.iteye.com/blog/2169269
今日推荐