问题 java.net.SocketException: Too many open files
java.net.SocketException: Too many open files
at java.net.Socket.createImpl(Socket.java:460)
at java.net.Socket.connect(Socket.java:587)
at sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:673)
at sun.net.NetworkClient.doConnect(NetworkClient.java:175)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:463)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:558)
at sun.net.www.protocol.https.HttpsClient.<init>(HttpsClient.java:264)
at sun.net.www.protocol.https.HttpsClient.New(HttpsClient.java:367)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(AbstractDelegateHttps
URLConnection.java:191)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1156)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1050)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnec
tion.java:177)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:162)
at com.tsing.util.HttpRequestUtil.sendGet(HttpRequestUtil.java:44)
原因是:当单个进程打开的文件句柄(文件操作符)数量,超过了系统配置的上限值时,就会报错误“Socket/File:Can’t open so many files。
ulimit -a 可以查看系统目前文件句柄(文件操作符)数量限制
[root@gongjiaoyoudao-2 ~]# 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) 256996
max locked memory (kbytes, -l) 64
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) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 256996
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
open files 默认是1024 ,可以设置更多
查看资料,发现可以用下面的命令设置更大的文件句柄数量
ulimit -n 1000000
使用ulimit命令有一个缺陷,该命令仅仅只能修改当前用户环境的一些基础限制,仅在
当前用户环境有效。也即是说,在当前的终端工具连接当前shell期间,修改是有效的;一旦
断开用户会话,或者说用户退出Linux后,它的数值就又变回系统默认的1024了。并且,系
统重启后,句柄数量又会恢复为默认值。
ulimit命令只能用于临时修改,如果想永久地把最大文件描述符数量值保存下来,可以
编辑/etc/rc.local开机启动文件,在文件中添加如下内容:
ulimit -SHn 1000000
以上示例增加-S和-H两个命令选项。选项-S表示软性极限值,-H表示硬性极限值。硬性
极限是实际的限制,就是最大可以是100万,不能再多了。软性极限值则是系统发出警告
(Warning)的极限值,超过这个极限值,内核会发出警告。
普通用户通过ulimit命令,可将软极限更改到硬极限的最大设置值。如果要更改硬极限,
必须拥有root用户权限。
终极解除Linux系统的最大文件打开数量的限制,可以通过编辑Linux的极限配置文件
/etc/security/limits.conf来解决,修改此文件,加入如下内容:
* soft nofile 1000000
* hard nofile 1000000
soft nofile表示软性极限,hard nofile表示硬性极限。
回到我遇到的问题,先分析代码原因,发现可能原因是连接异常了,但是没有关闭资源,一直占用着资源。
((HttpURLConnection)connection).disconnect();
查看问题时,可以先查看clostwait的命令 clost_wait数量过多就不正常
netstat -n | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}’ 查看closewait命令
LAST_ACK 19
CLOSE_WAIT 13
ESTABLISHED 4885
FIN_WAIT1 15
TIME_WAIT 3985
记录一些操作的命令
ulimit -a
netstat -atnlp # 直接使用ip地址列出所有处理监听状态的TCP端口,且加上程序名
**lsof -i** – 显示所有连接
**lsof -p pid** – 使用-p查看指定进程ID已打开的内容