程序退出后,生成了一个 hs_err_pid1301132.log 文件,前面的内容如下,可以根据这个判断出是什么原因导致的吗?
1
jiom 43 天前
ulimit -a 看看系统有没有做参数优化
|
2
dx123 43 天前
看看你的 JVM 参数和配置呢
|
3
iyiluo 43 天前
jvm 没配置 core dump ,这点日志看不出什么。看谷歌结果貌似是 netty 报的错,检查一下代码或者加 core dump 参数后等复现吧
|
4
Geekerstar OP @jiom 没有优化过:
real-time non-blocking time (microseconds, -R) unlimited core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 513419 max locked memory (kbytes, -l) 16438992 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) 513419 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited |
5
Geekerstar OP @dx123 -Xmx2048m -Xms2048m -XX:+UseG1GC 没有做其他的优化
|
6
Geekerstar OP @iyiluo 好的,感谢
|
7
serverKnignt 43 天前
是不是被 Linux kill 了?
|
8
serverKnignt 43 天前
@serverKnignt 可以看下日志,cat /var/log/messages | egrep -T -C10 Kill
|
9
ZZ74 43 天前 1
jvm 退出最常见的就是内存不够了,要么是堆内存,要么是堆外内存。 结合 ByteBuffer 和 SIGSEGV ,堆外可能性最大。具体的得描述下你的程序是干嘛的,以及更多 log
|
10
Geekerstar OP @iyiluo 我的错误和这个很像,难道真的是 Netty 的问题? https://github.com/netty/netty/issues/4206
|
11
Geekerstar OP @serverKnignt #7 应该不是,查了系统日志没发现啥问题
|
12
Geekerstar OP @ZZ74 我从监控平台看了下内存那些都很正常的呢? https://imgse.com/i/pAGLDy9
https://imgse.com/i/pAGLBQJ 程序有大量的 IO 和 CPU 操作,用的 undertow 框架。 |
13
willbetter 43 天前
可能是磁盘空间不足或者是打开的文件数据过多了
|
14
ZZ74 43 天前
@Geekerstar 你贴的 gihub 的例子就是 memory 问题啊,而且人家也给出了 netty 配置。
hs_err_pid1301132.log 文件内容远不止于此,github 上面就详细多了,能看到 oom 报错还有 Event: 984.476 GC heap before ParOldGen total 2796544K, used 2796216K object space 2796544K, 99% used 你那个监控中的 45 到 9 点那一下 memory 的异常大量分配很值得怀疑,之后没数据了,持续 full GC 崩溃了导致没数据了吧 |
15
Geekerstar OP @ZZ74 #14 大佬能否帮忙分析一下呢?实在找不到问题了,这是几张完整的监控截图。大概八点四五十的时候用户开始使用的,之后没数据是因为 JVM 退出了。
https://imgse.com/i/pAJpwrD https://imgse.com/i/pAJp0qe https://imgse.com/i/pAJpdKO 这是 hs_err_pid1301132.log 文件 pan 点 baidu 点 com/s/1hZ5Fb8Nir458vSiS14XY-Q 提取码: cgpp |
16
D3EP 43 天前
程序有手动控制 Netty ByteBuf 的逻辑吗?之前接手过一个 RPC 框架,在一些业务场景下出现类似的 Segment Fault ,发现是在某个地方释放了 ByteBuf ,但后面又往里写数据最终 core 掉了。
|
17
Geekerstar OP @D3EP 没有哦,我们程序有 websocket 推送,而且 web 框架是用的 undertow ,好像底层有 netty ,但是没有直接在业务代码里操作 netty
|
18
Geekerstar OP @willbetter 磁盘还有几个 T ,文件句柄看日志也正常范围
|
20
ZZ74 43 天前
SEGV_MAPERR 错误,崩溃前平凡 FGC ,但是内存能下来,看起来有临时大对象。AbstractFramedChannel.flushSenders()的时候崩了。
我不知道 undertow 用的堆内还是堆外。有可能是因为 ByteBuf 大小有限 把 java 大对象写入 ByteBuf 时导致的。也不排除 16 楼说的。 你可以结合你的系统特点看看。看起来是个物联网数据采集系统不知道 flushSenders 是在给设备发数据还是提供查询。 |
21
Geekerstar OP @ZZ74 #20 感谢大佬,AbstractFramedChannel.flushSenders()应该是 undertow 底层推送 ws 的时候调用的,系统中有 websocket 推送,数据量和频次很高,快的话几毫秒一次。但是据说出问题那会儿没有停留在有 ws 推送的页面。flushSenders 是给 web 客户端发送数据。
|
22
Geekerstar OP @ZZ74 #20 查了一下,Undertow 使用 Java NIO ( non-blocking I/O )来处理 WebSocket 和 HTTP 连接。NIO 会使用 ByteBuffer ,其中包括堆外内存( Direct ByteBuffer )。有可能和这个有关系么?
|
23
Solace202 43 天前
肯定是代码写的有问题,建议把最新版本和上次版本之间提交的代码 review 下,对于循环、查库 留意下,大概率是内存不够直接挂了
|
24
hideon 43 天前
有没有 heapdump? 看起来崩溃前存在频繁 GC 和对象生成, 结合使用 ws, 是不是瞬时连接增大导致的?
|
25
Geekerstar OP @hideon 没有手动 dump ,因为当时 JVM 直接挂了。也没有自动生成 Dump 文件。您说的这个 ws 瞬间连接增大有一定道理,但是我们这个是内网使用,不会有很多人同时使用。以前有过 OOM ,是因为 ws 连接一直没释放,导致后端有引用在无法回收部分垃圾。但是目前已经加了五分钟自动断开重连 ws 的机制了。ws 推送的频次和数据量确实很高。毫秒级的。
|
26
Geekerstar OP 操作系统是 ubuntu ,检查 syslog 日志,发现一个信息,不知道是否有关联:
1 、程序最后一行 info 日志时间是,2024-10-09 08:52:57.251 ,无错误日志。 2 、检查 Syslog 日志,发现同一秒有下面的日志: Oct 9 08:52:57 lenovo-07 systemd[1]: session-2106.scope: Deactivated successfully. Oct 9 08:52:57 lenovo-07 systemd[1]: session-2106.scope: Consumed 2w 1d 21h 28min 5.200s CPU time. |
27
hrapunzel 43 天前
可能是堆外内存爆了
|
28
ZZ74 43 天前
@Geekerstar 很可能啊,发送的是序列化后的 java 对象还是文件?一般来说 java 代码写入超过 byebuff 大小只会有 runtime 异常,但如果直接是文件的话就不一定了。比如发送时文件大小比之前分配好 bytebuff 时大了导致越界。
另外 XNIO-1 I/O-6" [_thread_in_Java 其他都是_thread_in_native 有一定并发可能 |
29
Geekerstar OP @hrapunzel 这个服务器 128g ,目前只用了十多 G
|
30
Geekerstar OP @ZZ74 #28 我们发送的是 JSON 的字符串,不是文件。您最后一句话是啥意思呢?是指可能是因为并发导致的吗
|
31
ZZ74 43 天前
@Geekerstar XNIO-1 I/O-x 这种线程理解没错的话 应该都是给 web 客户端发送数据的吧?
你可以比较下是不是每次崩 ,那个线程都是_thread_in_Java ,如果是的话考虑下大字符串 毕竟这个线程还没执行 native 代码。 因为你说你们没有操作 byebuff 那也有可能 undertow 高并发有 bug ,导致操作了正在被其他执行 native 代码的 byebuff 被这个线程用到了。 |
32
cyningxu 42 天前 via Android 1
太深奥了不懂,但还是每层楼都看完了,真的很喜欢这种氛围,大家一起帮忙解决问题,已经很久没在中文互联网看到这种场景了,现在大多都是冷嘲热讽。
|
33
hrapunzel 42 天前
@Geekerstar #29 堆外内存默认是 -Xmx 的大小, -XX:MaxDirectMemorySize 用这个参数指定一下
|
34
Geekerstar OP @hrapunzel #33 好的,我试一下,堆外内存默认 xmx 一样的 2g ,感觉 2g 应该够用了。我查了一下:如果 JVM 试图分配堆外内存(例如通过 ByteBuffer.allocateDirect()分配直接内存),但操作系统的内存资源已经耗尽,JVM 通常不会直接触发 SIGSEGV ,而是抛出 java.lang.OutOfMemoryError: Direct buffer memory 。JVM 本身一般不会直接因为堆外内存不足触发 SIGSEGV ,但如果程序使用了 JNI 、本地库或者使用了不安全的操作(例如 Unsafe 类),在处理内存时可能会导致 SIGSEGV
|
35
Geekerstar OP @cyningxu 是的,非常感谢大家,我也喜欢这种氛围。
|
37
xuanbg 42 天前
JVM 退出的话基本就是内存不足造成的,怕是接收到什么大数据,把分配给 JVM 的内存撑爆了
|
38
D3EP 42 天前
@Geekerstar #17 作为在互联网公司中间件团队的我只能说,没准儿是 undertow 或者 JDK 有 bug 。
|
39
LeegoYih 42 天前
遇到过有个生成图形验证码服务被 OOM Killer 杀过一次,没有 dump
|
40
jarvison 42 天前
太深奥了不懂,但还是每层楼都看完了,真的很喜欢这种氛围,大家一起帮忙解决问题,已经很久没在中文互联网看到这种场景了,现在大多都是冷嘲热讽。
|
41
julyclyde 42 天前
@Geekerstar session deactivated 啊?你在 shell 里手工启动的 java ??
|
42
Geekerstar OP @julyclyde #41 有启动脚本,我昨天也怀疑是不是在 shell 里手动启动的服务,但是和这个日期匹配不上。2w 1d 21h 28min 5.200 。这个日期要长于我们上次发版的日期。
|
43
spkingr 42 天前
楼主解决了吗?
可能是一个小问题,也可能是一个大问题,github 上那个问题居然是 epoll 的原因,太离谱了。 所以,有没有可能是使用了其他第三方库导致?加载了一些什么大对象,大的类型导致元空间放不下,建议把问题代码发给 AI 问下看有没有什么线索。 |
44
Geekerstar OP @spkingr 目前感觉大概率和 websocket 有关,排查了系统发现这种线程“XNIO-1 I/O-6” 只有在 websocket 断开连接的时候会使用。有可能是 websocket 断开连接的时候,有用到 undertow 和底层的 netty 的相关操作导致的。我怀疑是前端先建立某个连接,然后持续了很久,后端因为什么原因这个连接断开了,前端再发起断开连接请求,就导致这个问题。
|
45
Geekerstar OP @julyclyde #41 我顺着你的这个思路查了一下,应该是找到为啥提示 session deactivated 的原因了。9.23 日让客户改一下启动脚本,加一下打印 GC 日志的参数,结果客户把最后一句去掉了 > /dev/null 2>&1 & ,这个会导致持续将日志写到 nohup.out 里。
|
46
julyclyde 42 天前
@Geekerstar 如果是从 shell 里启动的话,那还真是受 ulimit 影响(不过,是这个脚本启动之前的 ulimit ,而不是你另外开一个 shell 查看的 ulimit ,即使这俩值相同,也是两码事)
后台服务,不应该在 user.slice 下启动;应该在 system.slice 下启动 |
47
spkingr 42 天前 via Android
@Geekerstar 这个 bug 后面重现了吗?如果重现,能不能禁用前端的 ws 再试试运行一段时间?最好是本地复现就好搞
|
48
Geekerstar OP @spkingr #47 目前为止没有复现,只出现了一次。要是能复现的话就能找到原因了。
|