17 June 2020
CPU飙高
- top查所有进程占用CPU的排序
- top -Hp 进程号,找到进程下线程占用CPU的情况,找到占用CPU最高的线程编号
- 执行print %x 线程号,转换成16进制,因为线程堆栈都是16进制数字
-
执行jstack 进程号 |
grep 线程号,查看线程堆栈信息,找到具体代码 |
- 线上除这种问题,应该没有这个时间去这么处理问题
- 首先判断有没有计算密集型的这种任务
- full gc导致cpu飙高(看堆情况,这个时候在jmap导出的话,有可能服务直接就死了,最好arthas)
- 为什么会full gc呢,batch insert插入大量的数据,每个插入都对应大对象,同时因为大批量的数据插入导致慢sql的出现,数据库链接被占用的更多,批量新增大对象的队列都满了,数据也没有释放,开始full gc,消耗cpu资源,导致问题出现
- 死循环(最好arthas)
- 解决方案
- 一般情况都不需要改回收机制,一般都是代码不规范的问题。考虑有没有大对象(大对象不止会OOM,也会cpu飙高,因为放不下这OOM,放的下full gc)
- 监控慢sql,这种存储媒介的资源很少,很重要,只要被异常占用,大概率会出问题
Arthas
线上OOM
- 简介:请求进来,创建对象,去内存里面申请空间,内存满了,触发full gc,gc之后内存依然爆满,OOM
- 影响
- 新请求不需要申请堆内存空间,正常用
- 新请求需要申请堆内存空间,进程飙高,操作系统认为危险,杀进程,服务宕机
- 解决
- 已经OOM宕机了,直接看dump文件,用jvm那个自带的工具分析下对象找到gcRoot,之后找到线程栈,之后找到问题
- 没有OOM宕机,如果执行jmap导出dump,会进行gc,会stop the world,很危险,所以最好用arthas
负载高,cpu低
- cpu负载值 = running 状态 + interruptible 状态的进程个数之和 。也就是说,如果负载值超过cpu核数,那表示出现了以下两种情况:
- 等待分配cpu资源的进程多了
- 等待磁盘I/O完成的进程多了
- 而导致等待磁盘I/O完成的进程过多的原因,又可能有如下几种情况
- 磁盘读写请多,导致大量I/O等待:前面通过 iostat 查看没有发现。
- MySQL存在没有索引的语句或存在死锁:服务器上个没有MySQL,而且通过前面查看,I/O请求量很少。
- 外接硬盘故障,常见如挂载NFS,但是NFS server 故障:这个问题会导致,大量请求无法获取到资源,从而interruptible 状态进程增多,负载增大
频繁full gc
- 首先看堆的变化情况,是否是缓慢增长还是一下子打满?
- 缓慢增加,有可能是内存泄露
- 一下子打满,应该是大对象进入,来源有可能是数据库,mq,内存主动产生
- 此时已经无法去打印出堆内存的情况了,因为cpu已经被打满了,首先排查数据库的问题
- 如果是数据库的话,查看是否有数据量过大的sql传输。
blog comments powered by