最近一段时间  某台服务器上的一个应用总是隔一段时间就自己挂掉      用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%

 
 
查找进程733下的线程  可以看到TID 线程775占用了96%且持有了很长时间  其实到这一步基本上能猜测到应该是    肯定是那段代码发生了死循环

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占用过高问题的排查及解决的更多相关文章

  1. 分析java程序中cpu占用过高的线程

    http://blog.csdn.net/jgwei/article/details/12079147 http://hllvm.group.iteye.com/group/topic/38893 h ...

  2. 黄聪:MYSQL使服务器内存CPU占用过高问题的分析及解决方法

    方法一: 使用 show processlist 语句,查找负荷最重的 SQL 语句,优化该SQL,比如适当建立某字段的索引. 方法二: #查看慢SQL日志是否启用mysql> show var ...

  3. 性能优化-CPU占用过高问题排查

    1. 性能优化是什么? 1.1 性能优化就是发挥机器本来的性能 1.2 性能瓶颈在哪里,木桶效应.   CPU占用过高 1.现象重现 CPU占用过高一般情况是代码中出现了循环调用,最容易出现的情况有几 ...

  4. 一次java Cpu占用过高的排查

    某一个项目CPU占用率一直很高,经常在40%-50%之间,最近比较闲,就开始了排查工作. 1.通过 jstack命令输出进程的堆栈信息 jstack 2788 >C:\log.txt 将堆栈信息 ...

  5. 【转】关于JVM CPU资源占用过高的问题排查

    http://my.oschina.net/shipley/blog/520062 一.背景: 先执行一个java程序里面开了两个线程分别都在while循环做打印操作. ? 1 # java -cp  ...

  6. 工具运行过程中,CPU占用过高的分析定位

    之前使用Java Swing开发了一款设备档案收集工具.支持多台设备同时收集,每个设备使用一个线程.在同时收集多台设备信息时,发现CPU占用率居然达到了97%,而且高居不下.显然这样的性能是令人无法忍 ...

  7. 一次单核CPU占用过高问题的处理

    客户现场反馈,top的检查结果中,一个CPU的占用一直是100%.实际上现场有4个CPU,而且这个服务器是mysql专属服务器. 我的第一反应是io_thread一类的参数设置有问题,检查以后发现re ...

  8. JVM的CPU资源占用过高问题的排查

    互联网后端架构 https://mp.weixin.qq.com/s/LiqAy2DikbmZzqogb5XRdA JVM的CPU资源占用过高问题的排查 互联网后端架构  今天 上午线上某应用的一台J ...

  9. 一个线上JVM的CPU资源占用过高问题的排查

    原文:https://www.iteye.com/blog/tyrion-2293369 上午线上某应用的一台JVM的CPU占比突然飙高到192%,并且一直下不来,导致监控一直告警,好久没处理这种问题 ...

随机推荐

  1. 生成器(generator,yield),next,send

    #生成器 def generator(): for i in range(200): yield '哇哈哈%s' %i g = generator() #调用生成数函数,接受作用 ret = g.__ ...

  2. (其他)window10分盘

    由于thinkpad的一个c盘大概是一个t左右,所以我们先分一下盘.   首先找到计算机管理,然后找磁盘管理,右击比较大的磁盘,压缩卷,大概就压缩一半吧,然后新建简单卷,一直下一步,紧接着就完成了. ...

  3. tkinter之grid布局管理器详解

    在很久之前,我发过一篇<tkinter模块常用参数>,里面已经几乎涵盖了tkinter的大部分教程. 好吧,其实也就是上一篇而已啦. 所谓布局,就是指控制窗体容器中各个控件(组件)的位置关 ...

  4. C#-封装(七)

    封装概念 C#是面向对象的一门语言,面向对象的语言有三大特性:封装.继承.多态.而封装可以实现一个自定义的类,从而定义新的对象 封装是将一个或多个项目集合在一个单元中,这个单元称之为类.这样可以防止对 ...

  5. SQL SERVER数据库级的触发器

    CREATE TRIGGER [Object_Change_Trigger_DDL] ON database FOR DROP_TABLE AS DECLARE @EventData AS xml; ...

  6. iOS 验证码按钮倒计时

    在app 注册或者登录 需要验证码的地方.为了避免短时间内刷验证码.往往会加上一层验证. 倒计时结束后.可以重新获取! 代码实现如下: // _CountdownTime 倒计时总时间: //_tim ...

  7. 归并排序python实现

    归并排序python实现 归并排序 归并排序在于把序列拆分再合并起来,使用分治法来实现,这就意味这要构造递归算法 首先是一个例子 原序先通过一半一半的拆分,然后: 然后再一步一步的向上合并,在合并的过 ...

  8. JavaScript获取IE版本号与HTML设置ie文档模式

    JavaScript获取IE版本代码: var gIE = getIE(); alert(gIE.version) function getIE() { var rmsie = /(msie) ([\ ...

  9. 为爱好舞蹈的人们做的软件,细究数据结构,操作系统,磁盘原理,用java/c/c++写一个开源 MP3助手

    1.可以给歌曲间插播空白音乐 2.拖拽式调整 3.先排序,后一键写入顺序文件. 国外的开源软件 MP3 播放排序  http://www.murraymoffatt.com/software-prob ...

  10. #006 C语言大作业学生管理系统第三天

    还差最后两部分 读取文件 恢复删除的学生信息 先学会处理文件的 知识点,再继续跟着视频做这个作业. 应该明天周六能把视频里手把手教的学生管理系统敲完 第二周尽量自己能完成C语言课本最后面那道学生管理系 ...