记一次线上JVM crash的问题解决过程
- 问题发生
2019年1月23日 23:07 左右生产环境三台主力用于消费mq写入JDDL的程序几乎同时挂掉。 - 猜测1
三台docker容器属于一个宿主机,经查并不是 - 猜测2
JDDL(分库分表框架)的问题 - 操作
把JDDL版本升级,然后发布4台机器,观察
同时把问题机器直接重启不做任何改动,观察 - 出现差异
2019年1月25日早上8:03和9:03 旧有两台机器 再次crash。验证了第三步的猜想,但是为啥会这样呢? - 分析hs_error_pid文件
6.1 关键信息1
# SIGSEGV (0xb) at pc=0x00007ff98e86c325, pid=5312, tid=140705576441600
#
# JRE version: Java(TM) SE Runtime Environment (8.0_20-b26) (build 1.8.0_20-b26)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.20-b23 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# V [libjvm.so+0x858325] LoadKlassNode::make(PhaseGVN&, Node*, Node*, TypePtr const*, TypeKlassPtr const*)+0x45
6.1 关键信息2
Current thread (0x00007ff988322800): JavaThread "C2 CompilerThread9" daemon [_thread_in_native, id=5386, stack(0x00007ff891d6d000,0x00007ff891e6e000)]
6.3关键信息3
Current CompileTask:
C2:34358995 19842 ! 4 com.mysql.jdbc.ConnectionImpl::execSQL (452 bytes)
- 猜测3
jvm使用jit编译mysql驱动包中的com.mysql.jdbc.ConnectionImpl::execSQL方法时发生错误,因为JDDL框架对jdbc标准中的行为进行了重写,低版本可能有位置bug。 - 操作
使用XX:CompileCommand=exclude,com/mysql/jdbc/ConnectionImpl::execSQL
禁止JIT编译改方法,发预发布,继续观察。 - 定论和解决
1月25号执行的8步操作,中间过了个周末,没有再出现crash的问题,由此证明JDDL低版本jar确实有问题。
那解决方案就是两种,将JDDL升级至最新jar或者使用第8步的操作禁止JIT。
后续
JDDL-0.01版本究竟什么操作导致JIT期间crash呢?
参考
JIT相关
https://blog.csdn.net/sunxianghuang/article/details/52094859
https://blog.csdn.net/ning0323/article/details/75451955
JVM相关
https://www.zhihu.com/question/51132462/answer/124751186
https://www.slideshare.net/RednaxelaFX/java-crash
网友评论