最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java實(shí)戰(zhàn)CPU占用過高問題的排查及解決

 更新時(shí)間:2018年08月10日 08:45:27   作者:江湖前輩黃藥師  
這篇文章給大家分享了java實(shí)戰(zhàn)CPU占用過高問題的排查及解決方法,有需要的朋友們可以學(xué)習(xí)下。

最近一段時(shí)間 某臺(tái)服務(wù)器上的一個(gè)應(yīng)用總是隔一段時(shí)間就自己掛掉 用top看了看 從重新部署應(yīng)用開始沒有多長(zhǎng)時(shí)間CPU占用上升得很快

排查步驟

1.使用top 定位到占用CPU高的進(jìn)程PID

top

2.通過ps aux | grep PID命令

獲取線程信息,并找到占用CPU高的線程

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

3.將需要的線程ID轉(zhuǎn)換為16進(jìn)制格式

printf "%x\n" tid

4.打印線程的堆棧信息 到了這一步具體看堆棧的日志來定位問題了

jstack pid |grep tid -A 30

top 可以看出PID 733進(jìn)程 的占用CPU 172%

查找進(jìn)程733下的線程 可以看到TID 線程775占用了96%且持有了很長(zhǎng)時(shí)間 其實(shí)到這一步基本上能猜測(cè)到應(yīng)該是 肯定是那段代碼發(fā)生了死循環(huán)

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

線程ID轉(zhuǎn)換為16進(jìn)制格式

printf "%x\n" 775

查看java 的堆棧信息

jstack 733 |grep 307 -A 30

顯然是 SmsQueueServiceImpl 中的produceMissSms 和 consumeMissSms 方法有問題

一下為精簡(jiǎn)的部分代碼

/** * Created by dongxc on 2015/7/7. 通知消息隊(duì)列 */
@Service("smsQueueService")
public class SmsQueueServiceImpl {
 // 生產(chǎn)異常隊(duì)列方法
 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("通知消息異常隊(duì)列生產(chǎn)消息返回失敗!"+smsLogDo.getId()); } }catch(Exception e){
   * logger.error("通知消息異常隊(duì)列生產(chǎn)消息失??!", e); }
   */
 }

 // 消費(fèi)異常隊(duì)列方法
 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("通知消息隊(duì)列消費(fèi)方法失敗!", e);
   return null;
  }
 }
}

從很有年代感的垃圾代碼來看 這兩個(gè)方法并沒有什么問題 繼續(xù)往調(diào)用這兩個(gè)方法的上層排查

/**
 * Created by dongxc on 2015/7/7.
 * 消息通知監(jiān)控線程
 */
@Service("smsMonitorComsumer")
public class SmsMonitorComsumerImpl {

 @Autowired
 private SmsQueueServiceImpl smsQueueService;
 
 //取隊(duì)列里的任務(wù)消費(fèi)
 @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);//計(jì)算差多少分鐘
     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("發(fā)送站內(nèi)信息短信時(shí)線程執(zhí)行失敗2!", e);
    }
   }
  }



 }
}

很顯然 這里有一個(gè)while(true) 基本定位到問題了 while里面完全是沒有用的代碼

繼續(xù)往上層看誰來調(diào)用

/**
 * Created by dongxc on 2015/7/7.
 * 通知消息隊(duì)列
 */
@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();
  }

  
 }
}

在應(yīng)用一啟動(dòng)的時(shí)候 spring初始化的就會(huì)執(zhí)行這一段處理丟失消息的代碼 然后這段死循環(huán)代碼 沒有任何作用

解決方法 即 注釋掉whlie(true)這一段代碼

案例一下,其實(shí)之前也遇到過CPU占用很高的問題, 但是那次是 頻繁的GC導(dǎo)致的

其實(shí)排查問題 的過程中也是在不斷的學(xué)習(xí)的過程

相關(guān)文章

  • Java常用API類之Math System tostring用法詳解

    Java常用API類之Math System tostring用法詳解

    System類代表系統(tǒng),系統(tǒng)級(jí)的很多屬性和控制方法都放置在該類的內(nèi)部。該類位于java.lang包,Java 的 Math 包含了用于執(zhí)行基本數(shù)學(xué)運(yùn)算的屬性和方法,如初等指數(shù)、對(duì)數(shù)、平方根和三角函數(shù),toString() 方法用于返回以一個(gè)字符串表示的 Number 對(duì)象值
    2021-10-10
  • java實(shí)現(xiàn)ATM取款項(xiàng)目

    java實(shí)現(xiàn)ATM取款項(xiàng)目

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)ATM取款項(xiàng)目的實(shí)現(xiàn)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • java調(diào)用微信現(xiàn)金紅包接口的心得與體會(huì)總結(jié)

    java調(diào)用微信現(xiàn)金紅包接口的心得與體會(huì)總結(jié)

    這篇文章主要介紹了java調(diào)用微信現(xiàn)金紅包接口的心得與體會(huì)總結(jié),有需要的朋友可以了解一下。
    2016-11-11
  • Java開發(fā)實(shí)現(xiàn)猜拳游戲

    Java開發(fā)實(shí)現(xiàn)猜拳游戲

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)猜拳游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • mybatis中的mapper.xml使用循環(huán)語句

    mybatis中的mapper.xml使用循環(huán)語句

    這篇文章主要介紹了mybatis中的mapper.xml使用循環(huán)語句,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • java中的序列化解析

    java中的序列化解析

    這篇文章主要介紹了java中的序列化解析,為了將對(duì)象進(jìn)行網(wǎng)絡(luò)傳輸或者是持久化,我們需要將對(duì)象的狀態(tài)信息轉(zhuǎn)換為可以存儲(chǔ)或者傳輸?shù)男问?這個(gè)轉(zhuǎn)換的過程就叫序列化,需要的朋友可以參考下
    2023-09-09
  • SpringCloud中的Consul詳解

    SpringCloud中的Consul詳解

    這篇文章主要介紹了SpringCloud中的Consul知識(shí),本文使用的是docker-compose方式管理consul服務(wù),直接啟動(dòng)即可,需要的朋友可以參考下
    2022-03-03
  • Java中的HashMap和Hashtable區(qū)別解析

    Java中的HashMap和Hashtable區(qū)別解析

    這篇文章主要介紹了Java中的HashMap和Hashtable區(qū)別解析,HashMap和Hashtable都實(shí)現(xiàn)了Map接口,但決定用哪一個(gè)之前先要弄清楚它們之間的區(qū)別,主要的區(qū)別有線程安全性、同步和速度,需要的朋友可以參考下
    2023-11-11
  • MyBatis中criteria的or(或查詢)語法說明

    MyBatis中criteria的or(或查詢)語法說明

    這篇文章主要介紹了MyBatis中criteria的or(或查詢)語法說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • MyBatis使用接口映射的方法步驟

    MyBatis使用接口映射的方法步驟

    映射器是MyBatis中最核心的組件之一,本文主要介紹了MyBatis使用接口映射的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-07-07

最新評(píng)論

岑溪市| 务川| 行唐县| 象州县| 拜城县| 巴彦县| 隆子县| 皋兰县| 乌拉特后旗| 江川县| 平顺县| 张北县| 义乌市| 吉首市| 高安市| 建昌县| 大洼县| 阳原县| 阿合奇县| 察隅县| 石渠县| 永新县| 呼和浩特市| 沁源县| 类乌齐县| 宜宾市| 安庆市| 普兰店市| 双柏县| 宁强县| 寻乌县| 建平县| 屏东市| 开封县| 桦甸市| 资阳市| 姜堰市| 汉寿县| 临洮县| 镇赉县| 新邵县|