java 一次CPU占用过高问题的排查及解决
最近一段时间 某台服务器上的一个应用总是隔一段时间就自己挂掉 用top看了看 从重新部署应用开始没有多长时间CPU占用上升得很快
排查步骤
1.使用top 定位到占用CPU高的进程PID
top
2.通过ps aux | grep PID命令
获取线程信息,并找到占用CPU高的线程
ps -mp pid -o THREAD,tid,time | sort -rn
3.将需要的线程ID转换为16进制格式
printf "%x\n" tid
4.打印线程的堆栈信息 到了这一步具体看堆栈的日志来定位问题了
jstack pid |grep tid -A 30
---------------------------------------------------------------------------- 华丽的分割线 ------------------------------------------------------------------------------------------------------------------
top 可以看出PID 733进程 的占用CPU 172%

ps -mp 733 -o THREAD,tid,time | sort -rn

线程ID转换为16进制格式
printf "%x\n" 775

查看java 的堆栈信息
jstack 733 |grep 307 -A 30


显然是 SmsQueueServiceImpl 中的produceMissSms 和 consumeMissSms 方法有问题
一下为精简的部分代码
/**
* Created by dongxc on 2015/7/7. 通知消息队列
*/
@Service("smsQueueService")
public class SmsQueueServiceImpl {
// 生产异常队列方法
public void produceMissSms(SmsLogDo smsLogDo) {
/*
* try{ String key = EnumRedisPrefix.SMS_QUEUE_MISS_DEAL.getValue(); boolean result = redisService.lpush(key,
* smsLogDo, 0); if(result==false){ logger.error("通知消息异常队列生产消息返回失败!"+smsLogDo.getId()); } }catch(Exception e){
* logger.error("通知消息异常队列生产消息失败!", e); }
*/
}
// 消费异常队列方法
public SmsLogDo consumeMissSms() {
try {
String destKey = EnumRedisPrefix.SMS_QUEUE_MISS_DEAL.getValue();
SmsLogDo smsLogDo = new SmsLogDo();
Object obj = null;
if (obj == null) {
return null;
} else {
smsLogDo = (SmsLogDo) obj;
}
return smsLogDo;
} catch (Exception e) {
logger.error("通知消息队列消费方法失败!", e);
return null;
}
}
}
从很有年代感的垃圾代码来看 这两个方法并没有什么问题 继续往调用这两个方法的上层排查
/**
* Created by dongxc on 2015/7/7.
* 消息通知监控线程
*/
@Service("smsMonitorComsumer")
public class SmsMonitorComsumerImpl { @Autowired
private SmsQueueServiceImpl smsQueueService; //取队列里的任务消费
@Transactional(propagation= Propagation.NOT_SUPPORTED)
public void run() { while (true) {
try {
SmsLogDo smsLogDo = smsQueueService.consumeMissSms();
Boolean result = false;
if(smsLogDo!=null){
long diff = (new Date()).getTime() - smsLogDo.getSendtime().getTime() ;
long min = diff%(1000*24*60*60)%(1000*60*60)/(1000*60);//计算差多少分钟
if(min>5){
result = true;
}
}
if(result){
smsQueueService.produceSms(smsLogDo);
}else{
smsQueueService.produceMissSms(smsLogDo);
}
} catch (Exception ex) {
try{
Thread.sleep(3000);
}catch(Exception e){
//logger.error("发送站内信息短信时线程执行失败2!", e);
}
}
} }
}
很显然 这里有一个while(true) 无数个草泥马策马奔腾 ps:垃圾代码看多了, 我已经不愤怒了.
基本定位到问题了 while里面完全是没有用的代码

继续往上层看谁来调用
/**
* Created by dongxc on 2015/7/7.
* 通知消息队列
*/
@Service("smsLogRunThread")
public class SmsLogRunThreadImpl {
public int flag;
@Autowired
private SmsLogConsumerImpl smsLogConsumer;
@Autowired
private SmsMonitorComsumerImpl smsMonitorComsumer; @PostConstruct
public void init() { if(ip!=""&&host!=""&&ip.equals(host)){
Thread thread = new Thread(){
public void run() {
smsLogConsumer.run();
}
};
thread.start();
Thread thread1 = new Thread(){
public void run() {
smsMonitorComsumer.run();
}
};
thread1.start();
} }
}
在应用一启动的时候 spring初始化的就会执行这一段处理丢失消息的代码 然后这段死循环代码 没有任何作用
解决方法 即 注释掉whlie(true)这一段代码
重新部署后 cpu占用就很正常了

案例一下,其实之前也遇到过CPU占用很高的问题, 但是那次是 频繁的GC导致的
其实排查问题 的过程中也是在不断的学习的过程 ! 先打个鸡血,我要继续搬砖了
java 一次CPU占用过高问题的排查及解决的更多相关文章
- 分析java程序中cpu占用过高的线程
http://blog.csdn.net/jgwei/article/details/12079147 http://hllvm.group.iteye.com/group/topic/38893 h ...
- 黄聪:MYSQL使服务器内存CPU占用过高问题的分析及解决方法
方法一: 使用 show processlist 语句,查找负荷最重的 SQL 语句,优化该SQL,比如适当建立某字段的索引. 方法二: #查看慢SQL日志是否启用mysql> show var ...
- 性能优化-CPU占用过高问题排查
1. 性能优化是什么? 1.1 性能优化就是发挥机器本来的性能 1.2 性能瓶颈在哪里,木桶效应. CPU占用过高 1.现象重现 CPU占用过高一般情况是代码中出现了循环调用,最容易出现的情况有几 ...
- 一次java Cpu占用过高的排查
某一个项目CPU占用率一直很高,经常在40%-50%之间,最近比较闲,就开始了排查工作. 1.通过 jstack命令输出进程的堆栈信息 jstack 2788 >C:\log.txt 将堆栈信息 ...
- 【转】关于JVM CPU资源占用过高的问题排查
http://my.oschina.net/shipley/blog/520062 一.背景: 先执行一个java程序里面开了两个线程分别都在while循环做打印操作. ? 1 # java -cp ...
- 工具运行过程中,CPU占用过高的分析定位
之前使用Java Swing开发了一款设备档案收集工具.支持多台设备同时收集,每个设备使用一个线程.在同时收集多台设备信息时,发现CPU占用率居然达到了97%,而且高居不下.显然这样的性能是令人无法忍 ...
- 一次单核CPU占用过高问题的处理
客户现场反馈,top的检查结果中,一个CPU的占用一直是100%.实际上现场有4个CPU,而且这个服务器是mysql专属服务器. 我的第一反应是io_thread一类的参数设置有问题,检查以后发现re ...
- JVM的CPU资源占用过高问题的排查
互联网后端架构 https://mp.weixin.qq.com/s/LiqAy2DikbmZzqogb5XRdA JVM的CPU资源占用过高问题的排查 互联网后端架构 今天 上午线上某应用的一台J ...
- 一个线上JVM的CPU资源占用过高问题的排查
原文:https://www.iteye.com/blog/tyrion-2293369 上午线上某应用的一台JVM的CPU占比突然飙高到192%,并且一直下不来,导致监控一直告警,好久没处理这种问题 ...
随机推荐
- (后台)SQL Server 代理(已禁用代理 XP) 怎么解决(转)
百度知道搜索的答案: 在SQL Server Management Studio中连接到SQL Server实例后,会显示“SQL Server 代理”节点.如果当前该实例的Agent服务没有启动,“ ...
- c/c++连通图的遍历(深度遍历/广度遍历)
连通图的遍历(深度遍历/广度遍历) 概念:图中的所有节点都要遍历到,并且只能遍历一次. 深度遍历 广度遍历 深度遍历 概念:从一个给定的顶点开始,找到一条边,沿着这条边一直遍历. 广度遍历 概念:从一 ...
- Java的基础知识四
一.Java 流(Stream).文件(File)和IO Java.io 包几乎包含了所有操作输入.输出需要的类.所有这些流类代表了输入源和输出目标. Java.io 包中的流支持很多种格式,比如:基 ...
- adb 的常见问题与处理办法两三
问题1:无法安装手机驱动, 解决方法:安装强大的豌豆荚,通常能都能解决问题 问题2: adb devices 时出现 adb devicesadb server is out of date. ki ...
- 使用epoll实现聊天室功能,同时比较epoll和select的异同
1.首先介绍一下select和epoll的异同,如下(摘抄自https://www.cnblogs.com/Anker/p/3265058.html) select的几大缺点: (1)每次调用sele ...
- LeetCode算法题-Plus One(Java实现)
这是悦乐书的第156次更新,第158篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第15题(顺位题号是66).给定一个非空数字数组来表示一个非负整数,并给其加1.该数组已 ...
- 如何使用微信web开发者工具调试企业微信
最近因工作需要围绕着企业微信来进行调试,从而掏出了我的微信web开发者工具,在进行授权的时候微信web开发者工具成功的提示了我:“您未绑定企业微信开发者权限”.那么关键来了,因为我也百度过,发现也有很 ...
- python 类与类之间的关系
一.依赖关系(紧密程度最低) (1)简单的定义:就是方法中传递一个对象.此时类与类之间存在依赖关系,此关系比较低. (2)实例植物大战僵尸简易版 题目要求:创建一个植物,创建一个僵尸 1.植物:名字. ...
- JS DOM 实现删除和添加的功能
<!DOCTYPE html> <html> <head> <title>发表评论</title> <link rel="s ...
- MySQL高级知识(四)——Explain
前言:explain(执行计划),使用explain关键字可以模拟优化器执行sql查询语句,从而知道MySQL是如何处理sql语句.explain主要用于分析查询语句或表结构的性能瓶颈. 注:本系列随 ...