记录一次linux环境中java应用无法启动问题的排查过程

linux环境中java应用无法启动问题的排查过程

问题表象

某天,一个朋友找到我说自己有一个项目部署在云服务器上,现在系统登录的时候提示用户名密码错误,怀疑是密码被改了,由于之前的开发离职了,想让我帮忙想想办法修改一下密码。

step1

【思路1】 既然系统登录页面能访问,并且系统明确提示用户名密码错误,那程序应该是没问题,我只要想办法连上数据库把密码改一下应该就能解决了。
【疑惑1】 于是要到了远程服务器的方式,准备上去通过jar包的配置找到数据库连接地址直接动手,于是ps -ef|grep java,发现并没有java进程,瞬间感觉事情不妙,但没有想太多,通过history硬找到了应用的jar包,在application.yml中找到了mysql的连接地址就是localhost:3306,于是我又ps -ef | grep mysql,发现也没有进程。我擦,那应用和数据库都没启,系统咋能访问的?
【疑惑1-结论】 前后端分离通过nginx代理部署的项目可以在后端项目没有启动的情况下访问前端静态页面。于是我ps -ef | grep nginx,果然nginx是启动着的,从nginx.conf配置中也找到了dist文件确实存在,至此解决了刚才的疑惑。于是我紧接着启动了mysql,又启动了jar包,发现启动报错了,提示数据库连接失败。找了半天发现mysql的端口是3309,这哥们配置文件写的3306。这尼玛之前真的启动成功过吗。。。。
【思路1-结论】 废了半天劲终于把数据库搞定了,于是我赶紧去数据库里找到了user表,筛选出对应用户的密码,发现密码字段加密了(安全性做的还挺好),靠着我机智的头脑试出来是base64加密的,解密后发现密码并没有被改,至此说明登录不成功的原因并不是密码被修改导致的,思路1是错误的,需要重新找到问题的根本原因。
【阶段性结论1】 既然密码是对的,那应该没有问题呀,于是我怀着不信任的态度又在登录界面试了好几次,确实一直提示用户名密码错误。他喵的,难道不是连的这个数据库?于是我又确认了一下application.yml,确保了数据库没有连错。由于没有源码,我只得打开登录页面的F12看看,期望能发现点什么,果然发现login请求报nginx 502了,那说明后端服务访问不到?于是我ps -ef|grep java,果然没有java进程。至此说明登录失败的原因应该是后端服务一直没启起来。

step2

【疑惑2】 服务都没启起来,居然报用户名密码错误,这代码咋写的,等拿到源码一定要看看。
【思路2】 既然定位到是因为服务没启起来,那就得想办法找到服务没启动起来的原因,排查日志发现并无任何报错。联想到之前说的这台服务器中过毒,我的第一想法是是不是有人在服务器上装了杀毒软件,误把java应用当作病毒给杀了。
【思路2-结论】 经跟服务器维护人员确认后发现并没有安装杀毒软件,看来也不是这个原因。

step3

【思路3】 那是不是因为程序有问题导致内存崩了没启动起来?于是我打开了两个控制台,一个启动jar包,另一个使用top命令监控这服务器状态。结果发现:
记录一次linux环境中java应用无法启动问题的排查过程_第1张图片
我靠,应用一启动占用了200%+的内存,那肯定是程序占用cpu太多导致系统崩溃,程序中肯定有死循环之类的。至此我坚定的以为发现了问题的根本原因。
【思路3-结论】 在没有源码的情况下我只能通过反编译工具,我想着如果是这个原因那一定是启动的时候有加载缓存或者处理啥东西,可把所有的类都翻完也没有找到带@PostStructe和*cache相关类,同时也没有使用spring的xml配置文件方式。本来想着通过dump堆栈信息下来再看看的,但在这之前我查了一下linux的top命令中%CPU的含义,发现用不着dump堆栈信息了,压根不是程序的问题。

step4

【思路4】 百度发现linux top中**%CPU显示的是进程占用一个核的百分比**。一核?我这200%+启不起来,难道这服务器只有两核?我马上cat /proc/cpuinfo看了一下,结果如下:
记录一次linux环境中java应用无法启动问题的排查过程_第2张图片
他喵的,8核服务器,就算我应用占满了两核cpu也不至于挂了呀,那看看服务器整体cpu占用的平均值吧,其实刚刚图里有:
记录一次linux环境中java应用无法启动问题的排查过程_第3张图片
cpu的整体占用平均值居然占到了97%。我在top命令的基础上按了1,看到了各个cpu的占用情况:
记录一次linux环境中java应用无法启动问题的排查过程_第4张图片
终于水落石出:8核cpu被全部沾满了,所以我的应用启动的过程中抢不到cpu,进程自己就挂了
【思路4-结论】 联想到之前说过这台服务器曾中过挖矿病毒,那八九不离十是服务器就没清理过病毒,一问,果然如此。那现在就是想办法处理病毒了。首先我们得找到病毒进程,然后把它kill掉,杀掉以后你会发现它过一段时间又自启动了,那肯定有什么定时任务,所以得想办法把定时任务清掉,定时任务清掉以后重新启动服务器你会发现他又会自启动,所以linux启动程序里也需要删掉相关文件,具体可参照如何清理挖矿病毒。 病毒清理掉后重新启动应用,观察了一天,各项功能正常。

【疑惑2-结论】 后来拿到了源码
记录一次linux环境中java应用无法启动问题的排查过程_第5张图片
果然没考虑后端没启动的情况,只要有问题,全部提示’用户名密码错误’,哥们儿这写法有点不对哦。

补充

【补充1-Linux top命令里面%CPU和cpu(s)的差别】 Cpu(s)表示的是 所有用户进程占用整个cpu的平均值,由于每个核心占用的百分比不同,所以按平均值来算比较有参考意义。而%CPU显示的是进程占用一个核的百分比,而不是整个cpu(12核)的百分比,有时候可能大于100,那是因为该进程启用了多线程占用了多个核心,所以有时候我们看该值得时候会超过100%,但不会超过总核数*100。

【补充2-挖矿病毒】 前几年区块链比较火,由于区块链需要大量计算,所以出现了挖矿病毒,这个病毒的核心功能就是借助宿主机的计算能力用于区块链的节点计算。通过这个事我大概总结了挖矿病毒的特点:它在操作系统开机自启动里加了很多curl的进程,这些进程会定时自动联网注册一个-bash的进程,这个-bash进程就是挖矿病毒进程,他会把整个服务器的cpu全部沾满,导致应用无法启动。需要修改自启动的配置和清理掉所有curl进程。

你可能感兴趣的:(java,linux,服务器)