问题描述
早上一到公司,就有同事说项目出问题了,用户登录不上,于是我们开始排查问题。先是看了一下服务器上的服务是否死掉,发现服务还在运行,然后阿里云管理界面的CPU、内存等资源是否异常,发现各项指标都还算比较正常,只是在早上8点左右CPU有一个异常升高。查看nacos发现服务从nacos下线了。于是我们在页面访问了一下接口,发现接口都在报503,大概了解情况之后,我们先把日志拷下来,然后就把服务重启了,保证用户能够先使用。
然后我们开始查看日志,发现了服务有报OOM的情况
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zSRFDENL-1639645676413)
但是我们查看了阿里云的监控,发现内存一直都比较健康,都在50%左右,于是想到了配置文件中是否配置了JVM内存大小的,果然,查看配置文件之后发现,内存配置还是很小的,于是初步判定是用户量增大后,内存使用开始变高,然后内存设置又太小,所以导致了OOM,然后把配置增大到4G,看后面是否还会出现问题。
但是过了三个小时左右,用户反馈系统再次崩溃,我们也很疑惑,然后查看阿里云的监控发现,CPU再次飙升到80%左右,内存还是十分健康,访问接口发现还是报的503,查看系统日志发现,还是报了OOM问题,于是我们把系统的GC日志和dump文件备份了一下,重启系统。
在对GC日志进行分析后,发现堆内存出现了突然的升高,年老代突然被填满并超出限制,突破了我们设置的上限,如果是因为死循环问题一般CPU和内存都是逐步升高,而不是突然一下拉升到特别高的位置。因此我们怀疑是sql问题,于是我们查询了mysql的慢日志,发现有一条sql查询出的数据量特别大,有1000多万行,然后查询日志发现每次OOM前,也都有这个sql的日志打印,于是判定应该是某个定时器执行这个sql的时候加载大量数据到内存中导致内存超出限制。
在查找之后很快找到这个定时器,这个定时器是查询数据库中的敏感日志,然后调用腾讯接口进行一个降敏处理。由于敏感日志过多,并且之前写这个sql的人并没有将处理过的日志跑排除掉,所以导致查询了许多重复日志,导致数据量过大,于是我们在原来sql的基础上进行了业务优化,对处理过的日志不再进行处理。之后就没有再出现这个问题