SpringBoot的502问题排查及优化
最近这个问题,让我很头大,就是使用nginx进行转发的时候,总是会会出现502错误。
1.进程被意外杀死
这种情况其实就是一直出现502错误,也就是服务不可用的情况。在关键时刻,Spring Boot服务总是不可以使用,查看日志,我发现了是我使用的一个nacos服务无法被找到造成的,导致了Spring Cloud的loadBalancerClient出现服务不可用的现象。刚开始,我以为是nacos出现的问题,于是就去找了nacos的日志,但是因为nacos日志确实太多了,不知道从何查起。于是就先把服务重新启动了一遍,暂时解决了问题。
第二天到公司的时候,又出现了无法找到服务的问题。经过观察,是因为其中一个java进程被莫名奇妙杀死导致的,这个进程就是使用OAuth2编写的认证服务层。为什么每次都是杀死同一个进程呢?让我很不理解。这个时候,我想起了前几天发现的,每次tomcat进程总是被莫名奇妙的杀死的过程。
1 | ## 查看日志 |
当我使用上面相关命令查看系统日志的时候,发现了很多被杀死的进程,但是也只是显示了有java进程被杀死了,但是没有显示是这个进程是什么,叫什么名字,这个让我怎么查呢?
为了应对tomcat莫名其妙被杀死的情况,我当时是写了一个crontab定时脚本,每隔一分钟检查相关的进程是否被杀死,杀死之后,就重新启动该进程。(思来想去,可能这也不是一个长久之计啊)
1.Nacos跨服务器调用服务报错
2.Nacos跨服务器调用服务报错
3.查看Linux磁盘及内存占用情况 (查看系统中内存使用情况的各种命令)
4.过滤/var/log/messages中的net-snmp日志 (这里有如何过滤net-snmp日志的方法,但是不是我想要的)
5.Spring Boot引起的“堆外内存泄漏”排查及经验总结
6.关于linux:anon-rss和total-vm是什么意思
2.偶尔502情况
除了所有请求都是502的情况,还有就是出现的偶尔502的情况。比如我每隔10秒钟请求一次服务,在十次中,会有连续三次出现502错误,之前,和之后都是返回的200状态码。在我使用top进行查看的时候,发现每次出现502问题的时候,cpu都会很高。
1.java中502错误原因_Spring Boot连接超时导致502错误的实战案例 (这里主要是设置了tomcat的连接超时值)
2.SpringBoot 部署后访问502 Bad Gateway
3.排查过程
(1) 首先我同时打开了top工具和浏览器web tool,不断的观察,发现没过20几个请求之后,就会出现一次502。同时我可以获取到cpu使用过高的进程PID,根据PID,找到的程序是gateway网关程序。
(2) 使用 ps 命令多次打印进程id查看,发现只有一个gateway网关程序,一段时间后,PID就会改变。这个主要的原因就是我编写了定时任务,当进程被杀死的时候,会自动重启该进程,导致进程PID改变。
1 | ## 查看进程pid |
总结:根据上面的排查,那么可以得出结论,其实就是这个gateway程序cpu占用过高,被系统杀死,然后重启,重启之后,就会产生短暂的502,无法访问的问题。当然,最后的结果,其实也不全是动态路由的问题,主要的原因还是因为定时任务删除了gateway程序,出现的重启现象,但是我又不能给老板说是我自己的问题。
网上的大神总结的如何进行问题的检查的方法:
(1) 通过 top命令查看CPU情况,如果CPU比较高,则通过top -Hp <pid>命令查看当前进程的各个线程运行情况,找出CPU过高的线程之后,将其线程id转换为十六进制的表现形式,然后在jstack日志中查看该线程主要在进行的工作。这里又分为两种情况
如果是正常的用户线程,则通过该线程的堆栈信息查看其具体是在哪处用户代码处运行比较消耗CPU;
如果该线程是VM Thread,则通过jstat -gcutil <pid> <period> <times>命令监控当前系统的GC状况,然后通过jmap dump:format=b,file=<filepath> <pid>导出系统当前的内存数据。导出之后将内存情况放到eclipse的mat工具中进行分析即可得出内存中主要是什么对象比较消耗内存,进而可以处理相关代码;
(2) 如果通过 top 命令看到CPU并不高,并且系统内存占用率也比较低。此时就可以考虑是否是由于另外三种情况导致的问题。具体的可以根据具体情况分析:
如果是接口调用比较耗时,并且是不定时出现,则可以通过压测的方式加大阻塞点出现的频率,从而通过jstack查看堆栈信息,找到阻塞点;
如果是某个功能突然出现停滞的状况,这种情况也无法复现,此时可以通过多次导出jstack日志的方式对比哪些用户线程是一直都处于等待状态,这些线程就是可能存在问题的线程;
如果通过jstack可以查看到死锁状态,则可以检查产生死锁的两个线程的具体阻塞点,从而处理相应的问题。
1.系统运行缓慢,CPU 100%,以及Full GC次数过多问题的排查思路 (提到了很多的工具,jsatck、top工具等, 总结了多个方法)
2.spring cloud gateway cpu使用异常问题排查 (这里有说是日志大量记录导致的,但是我经过查询,发现并不是这种情况)
3.SpringCloud Gateway 动态路由配置导致cpu满载,内存耗完 (因为我也同样配置了动态路由,所以又可能是因为动态路由导致的问题)
4.Spring Cloud Gateway基于CPU使用率实现限流
4.查看系统内存及cpu使用率
1 | ## cpu及内存使用,PID:进程的ID,USER:进程所有者,PR:进程的优先级别,越小越优先被执行 |
1.面试官:JAVA进程突然消失怎么办? (主要原因有这三种:linux的OOM killer、JVM自身故障、JVM的OOM)
2.Java进程被杀死排查过程 (操作系统日志/var/log/messages错误日志,主要排查了oom-killer问题)
3.Linux系统查看CPU使用率的几个命令
4.Linux服务器如何查看CPU占用率、内存占用、带宽占用
5.Linux查看内存使用情况方法