Spring & JVM

一次生产 JVM CPU过高排查

双十一了,头一天晚上10点左右收到阿里云cpu超过90%短信报警,第二天上班了,操作步骤如下:

  • top找出cpu高的java进程号9592
  • top -Hp 9592查看cpu占用time最高的线程编号28178

说明: 这个命令就能显示刚刚找到的进程的所有线程的资源消耗情况。找到CPU负载高的线程tid 28178, 把这个数字转换成16进制,6e12(10进制转16进制,用linux命令: printf %x 172)

  • 执行 printf "%x\n" 28178 获取线程十六进制地址6e12 (十六进制一定要小写)
  • 执行jstack 9592 | grep -10 6e12 (十六进制线程号)
"http-bio-8121-exec-199" daemon prio=10 tid=0x00007f751804b800 nid=0x6e12runnab  le [0x00007f74ebcf9000]
   java.lang.Thread.State: RUNNABLE
        at com.xx.model.seller.SellerTransportModel.getFee(SellerTransportModel.java:387)
        at com.xx.model.seller.SellerTransportModel.calculateTransFeeFuil  (SellerTransportModel.java:312)
        at com.xx.model.cart.CartModel.getCartInfoByChooseId(CartModel.ja  va:1134)
        at com.xx.service.impl.cart.CartServiceImpl.getCartInfoByChooseAn  dId(CartServiceImpl.java:201)
  • 排查代码SellerTransportModel.java:387
for (int i = 0; i < surplus; i += addWeight) {
      // 此线程一直在执行这一行代码。。。也就是说死循环原因导致cpu一直高
      price = price.add(new BigDecimal(addFee));
}
  • 修改代码
 // 计算多出的钱
if(addWeight != 0){ // 线上死循环了
    for (int i = 0; i < surplus; i += addWeight) {
        price = price.add(new BigDecimal(addFee));
    }
}
  • 打包测试,紧急上线,over

留言

您的电子邮箱地址不会被公开。