# 信创中间件莫名崩溃宕机

# 背景

客户使用东方通、中创之类的信创中间件,部署了OA系统。最近突然出现中间件莫名崩溃,进程自动退出的问题,需要排查分析原因。

# 分析过程

明确现象是:OA系统突然全员无法使用。管理员访问服务器发现OA的Java进程已经不存在,中间件的进程也不存在,等于系统被主动杀死了。

中间件与OA的关系是:中间件是一个容器,OA是存放在容器中的运行元素。

正常情况下OA因为程序编码等问题引发的性能宕机,只会影响OA自身,表现是:OA进程存在、中间件进程也存在,只是内存或线程等因素导致OA不可用,不会影响中间件。

当前情况是OA进程、中间件进程都不存在,这种情况常见于JVM崩溃、外部杀毒软件主动杀死进程、外部攻击杀死进程。

# 第一条线索

首先,项目已经排除杀毒软件和外部攻击问题。然后最可能就是JVM崩溃,JVM崩溃通常会生成hs_err_pid文件,此文件会陈述JVM崩溃原因、崩溃时的线程快照,供技术人员分析。

但中间件厂商检查发现系统崩溃未见任何hs_err_pid文件,线索断掉!

# 第二条线索

通过coredump命令能看到Java进程确实存在主动退出的问题:

1737613891314.png

由于没有专业的coredump技术分析人员,此通路无法继续开展。

# 第三条线索

客户自己也在测试,最后发现每次打开某个表单后过一会儿系统就崩溃了。因为非常突然,从OA的日志中没有任何体现,也无法来得及抓取stack信息,OA侧分析通路也断掉了。

1737614065711.png

# 第四条线索

大家还是怀疑JDK问题,通过沟通,了解到客户使用的操作系统默认自带的JDK1.8 341版本,此版本已经大于标准产品发版的小版本号,属于较新的JDK,理论JDK越新,BUG越少。

1737614297215.png

后来,客户自己去Oracle官网查询到高于341版本的JDK有修复JVM C2 Crashes,于是客户更新了JDK版本。

1737614417636.png

更新后版本:

1737614570896.png

# 最终问题

更新JDK版本,重启系统后,重新访问崩溃的表单,终于弹出了正确的错误提示,如下图所示。

此问题信息很明确:客户在表单中注入了公式,公式中使用了类似于递归的代码编写方法,出现了无穷递归,将JVM的栈空间占满了,最后导出系统异常!公式是客户自己编写,解决方案就是找到这个公式的代码,优化程序,不要出现无限递归嵌套即可。

1737614584554.png

# 总结发散

综上,是因为系统中出现了递归嵌套调用,导致了StackOverflowError,又恰好触发了JDK对应版本的BUG,导致JVM莫名Crash。

正常来说递归只会让日志爆出StackOverflowError,影响当前那一次请求,不会把中间件搞崩。但这个问题在其它项目上确实遇到了类似案例:一个央企东方通中间件下,开发的java程序写了递归,没有抛出StackOverflowError,直接中间件崩溃,最后通过Review提交代码,才怀疑到问题点。

目前看,可能跟JVM不同版本对栈处理策略有关,遇到此类问题,尽量先升级一个更高的JDK版本再去观察!

编撰人:het