系统优化小记:CPU长时间满负荷运行

CPU长时间满负荷运行,一次入门级降CPU系统优化实战

现象

用户量增大,线上一个Java单应用服务长时间占用服务器CPU达到400%,使得接口响应速度非常慢,线程拥堵,出现各种响应超时问题,即便有时候没有用户操作,也会长时间占用大量CPU和内存。

解决思路

找出哪些程序处理满,进行排查优化(业务流程调整、锁关闭、SQL优化、一些耗性能的程序不使用内存方案)

解决方案

linux命令排查 + Arthas监控 + Druid sql 监控

解决方案:

一、Linux命令排查,方法如下:

1.显示进程列表,定位进程号

top命令下,按shift+H查看cpu占用最高进程(PID:21659)

2.显示线程列表,定位线程号,找到哪些线程占用高耗时长

命令:ps -mp pid -o THREAD,tid,time | sort -rn | more

ex:ps -mp 21659 -o THREAD,tid,time (shift+H)

ps:截图中pid写成24275原因是由于中途重启过一次程序,原PID:21659 变更成 PID:24275,实则都是同一个Java程序

其中TID:24737、24742、24745,耗时较长占用CPU率较高

3.将线程号转为系统可识别的16进制

命令:printf "%x\n" tid

4.打印线程的堆栈信息,分析原因

命令: jstack PID | grep [16进制TID] -A 30

ex:查看线程24737的堆栈信息, jstack 24275 | grep 60a1 -A 30

5.如果嫌以上操作麻烦,也可直接使用 jstack PID,打印出所有堆栈,进行查看。

二、辅助神器Arthas程序监控

本次不在说明,后出专题讲解,附上官方文档:

Arthas传送门

三、辅助Druid SQL监控

本次也不在说明,后出专题讲解,附一张图

最终问题定位在

堆内存占满,新创建对象时无法分配足够的内存,引起频繁GC

1.程序频繁请求RPC接口得到的响应慢,耗时过大;
解决方案:由于获取的数据实时性要求不高,改为缓存处理,避免实时请求。

2.客户端频繁请求某个接口,且接口中的sql效率非常低,导致了sql连接长时间被占用。
解决方案:由于该接口历史遗留,且和对应的调用客户端同事确认该接口现今已用处不大,因此注释掉了该接口。

3.频繁收到回调,随开启了多线程处理但由于有线程锁,使得其他线程被block,实则依然是个单线程处理,消费速度赶不上生产速度,线程积压。
解决方案:确保安全的情况下,关闭了线程锁。

4.代码逻辑不合理;
解决方案:重新调整代码逻辑

5.对数据库操作过于频繁;
解决方案:调整逻辑,优化sql(调整sql,加索引,避免全表扫描),尽量少操作数据库,多使用缓存对数据进行操作

总结

经过此次排查,虽最终问题得以缓解,但深知系统内依然存在很多其他性能问题,暴露出对JVM知识的欠缺,以及Java代码、SQL功底需要持续加强。保证程序系统的稳定,健壮,高效。


 Previous
Java设计模式 Java设计模式
概述: 本质:面向对象设计原则的实际运用,是对类的封装、继承和多态性以及类的关联关系和组合关系的充分理解。 分类: 1. 创建型模式:共5种,用于描述“怎样创建对象”,主要特点是“将对象的创建与使用分离”(解耦)。客户程序仅仅需要去使用对
2021-01-05
Next 
Docker,轻量级的虚拟化技术 Docker,轻量级的虚拟化技术
Docker 一个利用了lxc的技术的一个虚拟化引擎。 Docker简介什么是虚拟化​ 在计算机中,虚拟化(英语:Virtualization)是一种资源管理技术,是将计算机的各种实体资源,如服务器、网络、内存及存储等,予以抽象、转
2020-10-23
  TOC