Java 进程无故宕机,到底是人性的扭曲还是道德的沦丧(全是干货...)

        在 Java 开发与运维的过程中,我们常常会遇到一些棘手的问题,其中 Java 进程无故宕机堪称 “噩梦” 级别。相信不少同行都有过类似的困扰,本应稳定运行的 Java 进程,却毫无预兆地崩溃,就像一座坚固的大厦突然出现不明原因的坍塌。

        我在工作中就遇到两次这种情况,不过经过一系列深入的分析和排查,我成功找到了问题的根源并加以解决。在此,我想将这次“宝贵“的经验分享出来。这不仅是对自己解决问题历程的一个记录,更希望能为其他遭遇相同问题的开发者提供有价值的参考,帮助大家少走弯路,让 Java 进程重新稳定运行。

第一次遇到

        那是一个风和日丽的下午,领导安排我去排查一下服务器上Java进程经常无缘无故宕机的原因,我信心满满的接过了这个任务。

        鲁迅说过:遇事不决就看日志,我直接使用tail -n xxx.log 命令查看Java进程对应的日志文件,这一看不得了,啥都没有。wc不对劲啊,正常来说应该会输出对应的异常堆栈信息然后我根据堆栈信息找到原因,结果他硬是什么信息都没上一秒还在输出正常业务日志下一秒就水灵灵的宕机了。

        鲁迅还说过:遇事不决就去百度,我在百度输入“Java进程宕机没有任何日志”等关键字,一篇一偏的查看相关文章,这些文章介绍的可以能导致Java进程宕机的几个比较常见的也是比较容易排除的原因有如下几个:

  • Linux系统杀掉进程:Linux系统在内存不足时,会主动去杀掉一些进程,OOM-Killer机制
  • JVM自身奔溃:JVM自身故障导致进程没有时,会有一个hs_err_pid_xxx.log的文件生成,该文件的目录,默认是在工作目录下(启动的jar包所在目录),同样也可以通过Java启动参数来设置
  • 信号中断:如果进程收到了 SIGKILL 或其他终止信号(可能是其他用户或进程意外触发的),JVM 也可能立即退出且不输出日志。
  • OOM导致的退出:Java进程堆空间不足。

我依次按照百度出来的方法去一个一个排查,首先服务器的内存是够的,且服务器系统日志也没有杀死对应进程的记录。在启动命令添加-XX:ErrorFile=/var/log/hs_err_pid.log 但是宕机后也没有任何日志文件生成。使用JVM命令查看Java进程发现也一切正常。

        现在只剩下信号中断这个原因了,但是这个该如何排查呢,我索性直接把日志文件下载下来去看每一次宕机前都干了什么,结果还真让我发现了一些蛛丝马迹——每次宕机的时间点都一样,我马上想到这肯定跟定时任务有关,我开始排查代码中的定时任务,发现没有跟宕机时间点吻合的任务,我又去查看服务器上的定时任务发现也没有吻合的,接着又问领导,领导也说没配什么定时任务(他忘了)。

        突然我有一个大胆的想法,会不会是有外部的什么妖魔鬼怪之类的东西,每天定时黑入服务器将进程kill掉,我开始查看服务器的访问日志,别说还真有,每天宕机时间点的前一分钟有以root用户登录服务器的日志,我马上把我的发现告诉领导,我说我怀疑公司有间谍,领导沉默了其实我也觉得这离谱。不过领导此时好像想起了什么东西,他说让我到jenkins上看看。

        jenkins是啥,我开始百度大概了解了一下这玩意,然后要来jenkins的地址以及登录账号什么的,果然jenkins有个定时任务去构建项目,但是连续好几次构建失败,我看了看日志,发现每次都是构建完成后执行相关操作失败了。

        构建后首先将jar包上传,然后干掉进程,再启动进程,问题就出在启动进程这一步,会去执行服务器上的start.sh,但是目录错了应该执行下一目录的启动脚本,我重新改了一下点击build last启动成功,完美。

第二次遇到

        第二解决宕机问题就比较轻松了,也没有那么轻松,情况还是老样子,没有任何日志,这次不同的事确实没配什么定时人,应为这个项目我一个人写的,一个模拟商户项目用来对接我们正在开发的支付平台方便测试人员测试的以及产品向客户演示的。

        我首先检查了一下自己的代码看有没有不合理的地方,毕竟我此时还是个行业小白半吊子,但是不对劲的就来了,我自己本地从来没出现这种无故宕机的现象,只有在测试环境以及生产环境有这个问题,又听到产品说这周要给客户演示,我马上慌了跟带我的同事说了一下这个问题,他一开始以为是内存的问题,被问否定后,他马上说他知道一个原因,而且极大概率是这个原因。

        接着他发我一个另外一个项目的stop.sh里面内容如下:

#!/usr/bin/env bash
tokill=`ps -ef | grep java | grep 'jar前缀' | awk '{print $2}'`
kill -9 $tokill

就是这个jar前缀,这个项目的jar前缀和我的项目的jar包前缀重合了,所以原因就是同事每次发包时连着把我的项目也干掉了,改一下grep 后的关键字就行了,完美。

总结

        总结一下,这两次 Java 进程无故宕机,根本原因竟然都是意外的乌龙事件。第一次是 Jenkins 帮忙每天准时“宕机闹钟”,构建项目顺带“干掉”进程,偏偏领导和我都一时想不起来有这回事;第二次是同事的脚本操作精准打击,莫名其妙连我的项目都一并送上“西天”。所以,有时候 Java 进程就像一个脾气有点大的大厦管理员,遇到妖魔鬼怪才不管三七二十一直接跑路——可当你抽丝剥茧、一顿分析,才发现是自己给自己制造了些尴尬。

        遇到 Java 进程宕机,先冷静再细心,除了硬核分析,别忘了排查意料之外的“操作事故”。毕竟,世界上最深的不是海洋,是程序员挖的坑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值