遇到了个 Bug,查了下说是 tomcat 的 bug,新版本修复了,但是还会有这个问题?

2023-09-14 10:43:12 +08:00
 gzk329

ERROR org.apache.tomcat.util.net.Acceptor - Socket accept failed java.io.IOException: 打开的文件过多 at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method) at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:424) at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:252) at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:466) at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:72) at org.apache.tomcat.util.net.Acceptor.run(Acceptor.java:95) at java.lang.Thread.run(Thread.java:748)

一开始我是调大了系统连接限制,发现还是会有这个问题,时间长点才出现罢了,连接数我不想调成无限制。
我使用的是 tomcat 9.0.33 我查网上说是这个 bug tomcat 在 9.0.14 版本已经修复了?但我还是能遇到
这说明是我自己的代码有泄漏吗?感觉也不大可能啊
V 友 有遇到过吗?

2058 次点击
所在节点    Java
10 条回复
me1onsoda
2023-09-14 10:46:54 +08:00
是不是代码有问题,连接没释放掉?
gzk329
2023-09-14 10:58:12 +08:00
gzk329
2023-09-14 11:04:58 +08:00
snowlyg
2023-09-14 11:50:29 +08:00
代码有问题的可能性更大,一般的软件不可能有这么大的漏洞
yazinnnn
2023-09-14 14:00:01 +08:00
ulimit -n 看看

是不是代码里啥地方打开文件之后没关流?
crsmk01
2023-09-14 16:40:06 +08:00
LZ 发的问题现象、排查步骤以及 github 中的引文,说是是个 bug ,感觉有点牵强附会。

IOException:打开的文件过多,对应的英文应该是:Too many open files ,那应该查这个 Java 进程打开的文件描述符数和内容。

在 Linux&Unix 操作系统下运行 Java 程序,如果用 root 用户运行,默认只有操作系统层面的限制,root 用户本身没限制,如果是普通用户,那么受普通用户下执行 ulimit -Hn ( ulimit -n 显示的是 soft limit ,而 Java 应用程序需要看 hard limit )数值的影响。在一些 Linux 操作系统下,一个普通用户打开的文件描述符默认是 1024 ,这个数值太小了,调大成 65535 或者稍微更大的值并没有问题(本来默认值就有点小,需要优化)。
Linux 操作系统下,单进程可打开的文件描述符限制优先级:soft limit < hard limit < kernel (NR_OPEN => /proc/sys/fs/nr_open)

如果 Java 程序运行在普通用户下,ulimit -Hn 参数值也优化过了,还是报 Too many open files ,那得看看这个 Java 进程到底是因为打开了啥导致的异常,具体看:ls -l /proc/<Java 进程 pid>/fd | more (内容会有点多),看看是文件,还是 established or close_wait 状态的 TCP 连接占用的多,根据看看到的异常输出结果,再去查资料也不迟。

如果那个 Java 进程打开的文件描述符数处结果( ls -l /proc/<Java 进程 pid>/fd | more )也都正常,那就看看是不是操作系统层面所有用户、所有进程打开的文件描述符数是不是超过了操作系统最大允许打开的文件描述符数上限(/proc/sys/fs/file-nr )。
Saturn72
2023-09-14 16:50:59 +08:00
@tdy218 专业!
timeisweapon
2023-09-14 17:01:06 +08:00
按照#6 大佬的方法排查文件句柄数,个人经验大概率是应用的问题
ntop
2023-09-14 17:12:52 +08:00
我曾经遇到过类似的问题,但是并不是 java 而是其它语言,导致问题的原因是,当时有一个系统负责处理数据,大概逻辑就是一旦有一个请求过来我就会开启一个线程取读写数据库,但是如果同一时间产生了大量的读写请求并且读写操作耗时较长,那么就会在数秒之内打开太多的文件从而导致这个问题。
matepi
2023-09-15 08:35:36 +08:00
一般都是连接泄露
lsof -n -P > result.txt
然后拿下来看。

如果超大量 CLOSE_WAIT ,要考虑内部存在的服务请求等网络请求、在超时设定上的合理性。内层网络调用超时应小于外层网络调用超时,并逐层保证。如果使用 netty 等非线程池、使用事件 LOOP 处理的,更会容易触发此种情况。

同时,可以通过 jstack 等做个 threaddump 分析,有可能快速定位问题程序栈位置。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/973661

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX