# 信创中间件莫名崩溃宕机
# 背景
客户使用东方通、中创之类的信创中间件,部署了OA系统。最近突然出现中间件莫名崩溃,进程自动退出的问题,需要排查分析原因。
# 分析过程
明确现象是:OA系统突然全员无法使用。管理员访问服务器发现OA的Java进程已经不存在,中间件的进程也不存在,等于系统被主动杀死了。
中间件与OA的关系是:中间件是一个容器,OA是存放在容器中的运行元素。
正常情况下OA因为程序编码等问题引发的性能宕机,只会影响OA自身,表现是:OA进程存在、中间件进程也存在,只是内存或线程等因素导致OA不可用,不会影响中间件。
当前情况是OA进程、中间件进程都不存在,这种情况常见于JVM崩溃、外部杀毒软件主动杀死进程、外部攻击杀死进程。
# 第一条线索
首先,项目已经排除杀毒软件和外部攻击问题。然后最可能就是JVM崩溃,JVM崩溃通常会生成hs_err_pid文件,此文件会陈述JVM崩溃原因、崩溃时的线程快照,供技术人员分析。
但中间件厂商检查发现系统崩溃未见任何hs_err_pid文件,线索断掉!
# 第二条线索
通过coredump命令能看到Java进程确实存在主动退出的问题:
由于没有专业的coredump技术分析人员,此通路无法继续开展。
# 第三条线索
客户自己也在测试,最后发现每次打开某个表单后过一会儿系统就崩溃了。因为非常突然,从OA的日志中没有任何体现,也无法来得及抓取stack信息,OA侧分析通路也断掉了。
# 第四条线索
大家还是怀疑JDK问题,通过沟通,了解到客户使用的操作系统默认自带的JDK1.8 341版本,此版本已经大于标准产品发版的小版本号,属于较新的JDK,理论JDK越新,BUG越少。
后来,客户自己去Oracle官网查询到高于341版本的JDK有修复JVM C2 Crashes,于是客户更新了JDK版本。
更新后版本:
# 最终问题
更新JDK版本,重启系统后,重新访问崩溃的表单,终于弹出了正确的错误提示,如下图所示。
此问题信息很明确:客户在表单中注入了公式,公式中使用了类似于递归的代码编写方法,出现了无穷递归,将JVM的栈空间占满了,最后导出系统异常!公式是客户自己编写,解决方案就是找到这个公式的代码,优化程序,不要出现无限递归嵌套即可。
# 总结发散
综上,是因为系统中出现了递归嵌套调用,导致了StackOverflowError,又恰好触发了JDK对应版本的BUG,导致JVM莫名Crash。
正常来说递归只会让日志爆出StackOverflowError,影响当前那一次请求,不会把中间件搞崩。但这个问题在其它项目上确实遇到了类似案例:一个央企东方通中间件下,开发的java程序写了递归,没有抛出StackOverflowError,直接中间件崩溃,最后通过Review提交代码,才怀疑到问题点。
目前看,可能跟JVM不同版本对栈处理策略有关,遇到此类问题,尽量先升级一个更高的JDK版本再去观察!
