java.net.SocketException: Too many open files(转)
上一篇 / 下一篇 2012-07-05 14:52:04 / 个人分类:软件开发相关
部署到linux下的tomcat,今天发现包了“java.net.SocketException: Too many open files”,以前从来没有遇到过,在此记录一下:
彻底解决问题的是第三步, 所以,可以直接跳到第三步去看解决方法和步骤,当日第一、第二步是我不断探索,尝试解决问题的过程,虽然没有找到点上,但是还是有些意义的,因为linux切实有打开资源数量的限制,肯定需要修改的。
异常信息:
原因:
linux下有有文件限制,结果文件数操作最大限制,导致程序异常:问题是程序中有个静态方法打开文件时忘记关闭。两种解决方法,一是设置linux的最大文件打开数量(无法根本解决问题),二是解决程序中的bugs,即消除有问题的代码。
第一次解决
解决:
方法一、增大系统打开文件的数量(无法根本解决问题)、
1、默认linux同时最大打开文件数量为1024个,用命令查看如下:ulimit -a:查看系统上受限资源的设置(open files (-n) 1024):
2、可以修改同时打开文件的最大数基本可以解决:ulimit -n 4096
已经修改了最大打开文件数。
方法二、修改程序中的bugs:
程序中有个静态的方法打开文件后,没有关闭文件,导致每次请求都会去打开文件,在程序中填入关闭输入流的操作即可以:
问题彻底解决
-----
第二次解决:
实际测试后发现这个问题还没有解决,最终又找了些方法,经过一段时间的测试,似乎解决了问题:
具体步骤如下:
linux为redhat服务器版本(非个人版),必须设置的内容:
1、/etc/pam.d/login 添加
# 注意看这个文件的注释
具体文件的内容为:
修改后的内容:
彻底解决问题的是第三步, 所以,可以直接跳到第三步去看解决方法和步骤,当日第一、第二步是我不断探索,尝试解决问题的过程,虽然没有找到点上,但是还是有些意义的,因为linux切实有打开资源数量的限制,肯定需要修改的。
异常信息:
- ............
- Oct 17, 2011 5:22:41 PM org.apache.tomcat.util.net.JIoEndpoint$Acceptor run
- SEVERE: Socket accept failed
- java.net.SocketException: Too many open files
- at java.net.PlainSocketImpl.socketAccept(Native Method)
- at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:375)
- at java.net.ServerSocket.implAccept(ServerSocket.java:470)
- at java.net.ServerSocket.accept(ServerSocket.java:438)
- at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:59)
- at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:210)
- at java.lang.Thread.run(Thread.java:636)
- Oct 17, 2011 5:22:43 PM org.apache.tomcat.util.net.JIoEndpoint$Acceptor run
- SEVERE: Socket accept failed
- java.net.SocketException: Too many open files
- at java.net.PlainSocketImpl.socketAccept(Native Method)
- at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:375)
- at java.net.ServerSocket.implAccept(ServerSocket.java:470)
- at java.net.ServerSocket.accept(ServerSocket.java:438)
- at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:59)
- at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:210)
- at java.lang.Thread.run(Thread.java:636)
- Oct 17, 2011 5:22:44 PM org.apache.tomcat.util.net.JIoEndpoint$Acceptor run
- SEVERE: Socket accept failed
- java.net.SocketException: Too many open files
- at java.net.PlainSocketImpl.socketAccept(Native Method)
- at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:375)
- at java.net.ServerSocket.implAccept(ServerSocket.java:470)
- at java.net.ServerSocket.accept(ServerSocket.java:438)
- at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:59)
- at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:210)
- at java.lang.Thread.run(Thread.java:636)
- ............
- ............
- Oct 17, 2011 5:22:41 PM org.apache.tomcat.util.net.JIoEndpoint$Acceptor run
- SEVERE: Socket accept failed
- java.net.SocketException: Too many open files
- at java.net.PlainSocketImpl.socketAccept(Native Method)
- at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:375)
- at java.net.ServerSocket.implAccept(ServerSocket.java:470)
- at java.net.ServerSocket.accept(ServerSocket.java:438)
- at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:59)
- at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:210)
- at java.lang.Thread.run(Thread.java:636)
- Oct 17, 2011 5:22:43 PM org.apache.tomcat.util.net.JIoEndpoint$Acceptor run
- SEVERE: Socket accept failed
- java.net.SocketException: Too many open files
- at java.net.PlainSocketImpl.socketAccept(Native Method)
- at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:375)
- at java.net.ServerSocket.implAccept(ServerSocket.java:470)
- at java.net.ServerSocket.accept(ServerSocket.java:438)
- at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:59)
- at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:210)
- at java.lang.Thread.run(Thread.java:636)
- Oct 17, 2011 5:22:44 PM org.apache.tomcat.util.net.JIoEndpoint$Acceptor run
- SEVERE: Socket accept failed
- java.net.SocketException: Too many open files
- at java.net.PlainSocketImpl.socketAccept(Native Method)
- at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:375)
- at java.net.ServerSocket.implAccept(ServerSocket.java:470)
- at java.net.ServerSocket.accept(ServerSocket.java:438)
- at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:59)
- at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:210)
- at java.lang.Thread.run(Thread.java:636)
- ............
原因:
linux下有有文件限制,结果文件数操作最大限制,导致程序异常:问题是程序中有个静态方法打开文件时忘记关闭。两种解决方法,一是设置linux的最大文件打开数量(无法根本解决问题),二是解决程序中的bugs,即消除有问题的代码。
第一次解决
解决:
方法一、增大系统打开文件的数量(无法根本解决问题)、
1、默认linux同时最大打开文件数量为1024个,用命令查看如下:ulimit -a:查看系统上受限资源的设置(open files (-n) 1024):
- [root@**** bin]# ulimit -a
- core file size (blocks, -c) 0
- data seg size (kbytes, -d) unlimited
- scheduling priority (-e) 0
- file size (blocks, -f) unlimited
- pending signals (-i) 16384
- max locked memory (kbytes, -l) 32
- max memory size (kbytes, -m) unlimited
- open files (-n) 1024
- pipe size (512 bytes, -p) 8
- POSIX message queues (bytes, -q) 819200
- real-time priority (-r) 0
- stack size (kbytes, -s) 10240
- cpu time (seconds, -t) unlimited
- max user processes (-u) 16384
- virtual memory (kbytes, -v) unlimited
- file locks (-x) unlimited
- [root@**** bin]#
- [root@**** bin]# ulimit -a
- core file size (blocks, -c) 0
- data seg size (kbytes, -d) unlimited
- scheduling priority (-e) 0
- file size (blocks, -f) unlimited
- pending signals (-i) 16384
- max locked memory (kbytes, -l) 32
- max memory size (kbytes, -m) unlimited
- open files (-n) 1024
- pipe size (512 bytes, -p) 8
- POSIX message queues (bytes, -q) 819200
- real-time priority (-r) 0
- stack size (kbytes, -s) 10240
- cpu time (seconds, -t) unlimited
- max user processes (-u) 16384
- virtual memory (kbytes, -v) unlimited
- file locks (-x) unlimited
- [root@**** bin]#
2、可以修改同时打开文件的最大数基本可以解决:ulimit -n 4096
- [root@**** bin]# ulimit -n 4096
- [root@**** bin]# ulimit -a
- core file size (blocks, -c) 0
- data seg size (kbytes, -d) unlimited
- scheduling priority (-e) 0
- file size (blocks, -f) unlimited
- pending signals (-i) 16384
- max locked memory (kbytes, -l) 32
- max memory size (kbytes, -m) unlimited
- open files (-n) 4096
- pipe size (512 bytes, -p) 8
- POSIX message queues (bytes, -q) 819200
- real-time priority (-r) 0
- stack size (kbytes, -s) 10240
- cpu time (seconds, -t) unlimited
- max user processes (-u) 16384
- virtual memory (kbytes, -v) unlimited
- file locks (-x) unlimited
- [root@**** bin]#
- [root@**** bin]# ulimit -n 4096
- [root@**** bin]# ulimit -a
- core file size (blocks, -c) 0
- data seg size (kbytes, -d) unlimited
- scheduling priority (-e) 0
- file size (blocks, -f) unlimited
- pending signals (-i) 16384
- max locked memory (kbytes, -l) 32
- max memory size (kbytes, -m) unlimited
- open files (-n) 4096
- pipe size (512 bytes, -p) 8
- POSIX message queues (bytes, -q) 819200
- real-time priority (-r) 0
- stack size (kbytes, -s) 10240
- cpu time (seconds, -t) unlimited
- max user processes (-u) 16384
- virtual memory (kbytes, -v) unlimited
- file locks (-x) unlimited
- [root@**** bin]#
已经修改了最大打开文件数。
方法二、修改程序中的bugs:
程序中有个静态的方法打开文件后,没有关闭文件,导致每次请求都会去打开文件,在程序中填入关闭输入流的操作即可以:
- public static List<GpsPoint> getArrayList() throws IOException {
- List<GpsPoint> pointList = null;
- // 读取配置文件
- InputStream in = ParseGpsFile.class.getClassLoader().getResourceAsStream("GPS1.TXT");
- // 读路径出错,换另一种方式读取配置文件
- if (null == in) {
- System.out.println("读取文件失败");
- return pointList;
- }
- pointList = new ArrayList<GpsPoint>();
- try {
- BufferedReader br = new BufferedReader(new InputStreamReader(in));
- String longtude = "";
- String latude = "";
- String elevation = "";
- while ((longtude = br.readLine()) != null) {
- // 读下一行数据,读纬度
- latude = br.readLine();
- if (null == latude) {
- // 退出循环
- break;
- }
- // 读下一行数据,读海拔
- elevation = br.readLine();
- if (null == latude) {
- // 退出循环
- break;
- }
- // 加入一个点
- pointList.add(gps2point(longtude, latude, elevation));
- }
- in.close();
- System.out.println("\n\n");
- } catch (Exception e) {
- in.close();
- e.printStackTrace();
- }
- return pointList;
- }
- public static List<GpsPoint> getArrayList() throws IOException {
- List<GpsPoint> pointList = null;
- // 读取配置文件
- InputStream in = ParseGpsFile.class.getClassLoader().getResourceAsStream("GPS1.TXT");
- // 读路径出错,换另一种方式读取配置文件
- if (null == in) {
- System.out.println("读取文件失败");
- return pointList;
- }
- pointList = new ArrayList<GpsPoint>();
- try {
- BufferedReader br = new BufferedReader(new InputStreamReader(in));
- String longtude = "";
- String latude = "";
- String elevation = "";
- while ((longtude = br.readLine()) != null) {
- // 读下一行数据,读纬度
- latude = br.readLine();
- if (null == latude) {
- // 退出循环
- break;
- }
- // 读下一行数据,读海拔
- elevation = br.readLine();
- if (null == latude) {
- // 退出循环
- break;
- }
- // 加入一个点
- pointList.add(gps2point(longtude, latude, elevation));
- }
- in.close();
- System.out.println("\n\n");
- } catch (Exception e) {
- in.close();
- e.printStackTrace();
- }
- return pointList;
- }
问题彻底解决
-----
第二次解决:
实际测试后发现这个问题还没有解决,最终又找了些方法,经过一段时间的测试,似乎解决了问题:
具体步骤如下:
linux为redhat服务器版本(非个人版),必须设置的内容:
1、/etc/pam.d/login 添加
- session required /lib/security/pam_limits.so
# 注意看这个文件的注释
具体文件的内容为:
- [root@**** ~]# vi /etc/pam.d/login
- #%PAM-1.0
- auth [user_unknown=ignore success=ok ignore=ignore default=bad] pam_securetty.so
- auth include system-auth
- account required pam_nologin.so
- account include system-auth
- password include system-auth
- # pam_selinux.so close should be the first session rule
- session required pam_selinux.so close
- session optional pam_keyinit.so force revoke
- session required pam_loginuid.so
- session include system-auth
- session optional pam_console.so
- # pam_selinux.so open should only be followed by sessions to be executed in the user context
- session required pam_selinux.so open
- ~
- "/etc/pam.d/login" 15L, 644C
- [root@**** ~]# vi /etc/pam.d/login
- #%PAM-1.0
- auth [user_unknown=ignore success=ok ignore=ignore default=bad] pam_securetty.so
- auth include system-auth
- account required pam_nologin.so
- account include system-auth
- password include system-auth
- # pam_selinux.so close should be the first session rule
- session required pam_selinux.so close
- session optional pam_keyinit.so force revoke
- session required pam_loginuid.so
- session include system-auth
- session optional pam_console.so
- # pam_selinux.so open should only be followed by sessions to be executed in the user context
- session required pam_selinux.so open
- ~
- "/etc/pam.d/login" 15L, 644C
修改后的内容:
- -bash: [root@****: command not found
- [root@**** ~]# clear
- [root@**** ~]# cat /etc/pam.d/login
- #%PAM-1.0
- auth [user_unknown=ignore success=ok ignore=ignore default=bad] pam_securetty.so
- auth include system-auth
- account required pam_nologin.so
- account include system-auth
- password include system-auth
- # pam_selinux.so close should be the first session rule
- session required pam_selinux.so close
- session optional pam_keyinit.so force revoke
- session required pam_loginuid.so
- session include system-auth
- session optional pam_console.so
- # pam_selinux.so open should only be followed by sessions to be executed in the user context
- session required pam_selinux.so open
- # kevin.xie added, fixed 'too many open file' bug, limit open max files 1024, 2011
TAG:
我的栏目
标题搜索
日历
|
|||||||||
日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
1 | 2 | 3 | 4 | ||||||
5 | 6 | 7 | 8 | 9 | 10 | 11 | |||
12 | 13 | 14 | 15 | 16 | 17 | 18 | |||
19 | 20 | 21 | 22 | 23 | 24 | 25 | |||
26 | 27 | 28 | 29 | 30 | 31 |
我的存档
数据统计
- 访问量: 1074274
- 日志数: 555
- 文件数: 10
- 建立时间: 2011-06-21
- 更新时间: 2021-06-24