cpu占用过高解决方案实践

今天在查看项目服务器的时候,发现cpu一直占用99%多,于是就有了这篇文章。。。

1、找到占用cpu高的进程

通过top命令来查看cpu占用高的进程有哪些,如图:

top

在这里插入图片描述
这里的pid代表的就是进程id

2、查看当前进程内占用cpu的线程

通过命令来查到线程的id,如下:

//这里的2970就是第一步查到的占用cpu高的进程id,大写H小写p
top -H -p  2970

在这里插入图片描述
这里的pid代表着线程id

3、使用jstack命令来查看堆栈信息

需要注意几点:

  • 登录用户必须是当前服务的用户
  • 线程id需要转换为16进制

使用命令如下:

// 2970是进程id,f05是线程id3845的十六进制表示
jstack 2970 |grep  f05 -A 30

在这里插入图片描述
看看第一个就是占用cpu的罪魁祸首:

com.midea.cdp.microservice.sdk.quene.SdkQueneManager

4、在项目里进行优化

  • 问题:
    我在项目里找见了这个类:很明显里面有一个死循环,一定是他的原因,但是这个包不在项目里,而是用的二方库的包,也就是说这个代码我根本没办法修改。

    public class SdkQueneManager implements Runnable, ApplicationListener<ContextRefreshedEvent> {
        private static final Logger log = LoggerFactory.getLogger(SdkQueneManager.class);
        @Resource(
            name = "link_quene"
        )
        private BlockingQueue<SdkResult> bq;
        private IProjectAgentUdpService agentService;
    
        public SdkQueneManager() {
        }
    
        public void produce(SdkResult sr) throws InterruptedException {
            this.bq.put(sr);
        }
    
        public SdkResult consume() throws InterruptedException {
            return (SdkResult)this.bq.take();
        }
    
        public void run() {
        // 可以看到这里写了一个死循环
            while(true) {
                if (!this.bq.isEmpty()) {
                    SdkResult sr = null;
    
                    try {
                        sr = this.consume();
                    } catch (InterruptedException var3) {
                        var3.printStackTrace();
                        log.error(var3.getMessage(), var3);
                    }
    
                    this.agentService.submitResultQuene(sr);
                }
            }
        }
    
        public void onApplicationEvent(ContextRefreshedEvent event) {
            if (event.getApplicationContext().getParent() == null) {
                Thread t = new Thread(this);
                t.start();
            }
    
        }
    
        public void setAgentService(IProjectAgentUdpService agentService) {
            this.agentService = agentService;
        }
    }
    
  • 解决:
    既然不能修改,那我们利用类加载机制的双亲委派原理,在项目里创建一个一模一样的包和类,然后把死循环那一段注释调。通过尝试确实可以,问题得以解决。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值