个人技术学习

取是能力,舍是境界


  • 首页

  • 关于

  • 排行榜

  • 标签

  • 分类

  • 归档

  • 读书

  • 电影

  • 搜索

java.net.SocketException: Too many open files如何解决

发表于 2021-05-12 分类于 Java Hot: ℃
本文字数: 819 阅读时长 ≈ 1 分钟

近日,下班走后接收到业务反馈的一个错误,微信服务器向公众号推送消息或事件后,得到的回应不合法 次数: 5分钟 2731次。

看到是微信推送消息相关,然后看了眼时间,大概定位到了是定时通过微信公众号通知学生上课提醒的业务,所以立马通知开发去排查消息发送日志确定是什么问题。

但是开发查完消息发送日志,并没有发现相关线索,就去查看应用日志,最终才发现了大量如下的异常信息

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
java.net.SocketException: Too many open files
at java.net.Socket.createImpl(Socket.java:478)
at java.net.Socket.getImpl(Socket.java:538)
at java.net.Socket.setSoTimeout(Socket.java:1159)
at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:120)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:376)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:393)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute$original$0fedXLMr(InternalHttpClient.java:185)
at org.apache.http.impl.client.InternalHttpClient.doExecute$original$0fedXLMr$accessor$OtDgrqj0(InternalHttpClient.java)
at org.apache.http.impl.client.InternalHttpClient$auxiliary$OiYkCIMu.call(Unknown Source)
at org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstMethodsInter.intercept(InstMethodsInter.java:86)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
at cn.xxxxxxxx.notice.manager.component.impl.WXPushServiceImpl.doAction(WXPushServiceImpl.java:89)
at cn.xxxxxxxx.notice.manager.component.impl.WXPushServiceImpl.globalPush(WXPushServiceImpl.java:57)
at cn.xxxxxxxx.notice.service.component.WXSend.sendAndAck(WXSend.java:159)
at cn.xxxxxxxx.notice.service.component.WXSend.saveRecordAndSend(WXSend.java:139)
at cn.xxxxxxxx.notice.service.component.WXSend.doSend(WXSend.java:90)
at cn.xxxxxxxx.notice.service.component.AbstractSendFactory.lambda$send$0(AbstractSendFactory.java:132)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)

第一反应就是文件打开数超过 Linux 的限制了,莫非还是默认的 1024?。立即执行 ulimit -n 查看当前系统的文件打开符限制,得到的结果是 65535。

看到数字想起来早期已经统一设置了该参数了。继续查看上面的异常信息,发现了几个关键的地方

  1. java.net.SocketException

  2. org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:120)

由此大概率判断可能是网络资源没有得到释放导致?

所以立即执行了 netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' 命令,显示存在 40多万 个状态为 CLOSE_WAIT 的连接

然后执行 ll /proc/[PID]/fd |wc -l 查看当前应用进程是否有大量状态为 CLOSE_WAIT 的连接,继续应证了该想法。

接下来就比较明确了,进行 Code Review,查看 at cn.xxxxxxxx.notice.manager.component.impl.WXPushServiceImpl.doAction(WXPushServiceImpl.java:89) 相关区域的代码

找到了使用 HttpClient 的地方,确认了当时的开发未释放 httpclient 实例。

参考文章

Spoock/proc/$pid/fd是什么
  • 本文作者: Vito
  • 本文链接: https://alienwow.cc/posts/2021/05/java-SocketException-Too-many-open-files/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
# Java # SocketException
无法在 docker 中使用 libgdiplus
canvas绘制远程图片跨域的问题
  • 文章目录
  • 站点概览
Vito

Vito

取是能力,舍是境界
14 日志
10 分类
31 标签
GitHub WTM E-Mail
  1. 1. 参考文章
京ICP备16041040号-1 © 2016 – 2023 Vito | 站点总字数: 8k | 站点阅读时长 ≈ 8 分钟
由 Hexo 强力驱动 v3.9.0
|
主题 – NexT.Mist v7.3.0
| 友情链接: 卡拉云后台系统
|