前不久公司进行了一次大促,晚上值班。大促是从晚上8点多开始的,一开始流量慢慢的进来,观察了应用的各项指标,一切都是正常的,因为这是双11过后的第一次大促,想着用户的购买欲应该不会太强,所以我们的运维同事9点多就回家了在家里面远程支持,留下交易组和其它后端的技术值班,楼主就是交易组的。谁知10点整的时候我们的前置服务器突然告警,报资源占用过高。如下图:

  说实话,load超过10还是第一次见。。。。

  我是第一个发现情况的,所以我第一时间把告警信息发到群上之后,然后通知运维jstack当时的线程堆栈。就直接登录其中一台服务器用top -c 命令查看占用cpu最高命令的进程。发现是一个进程号为19988的java进程。然后用top -Hp 命令查看下面的线程。然后记录下来

过了几分钟之后收到运维主管发过来的jstack的文件,一个66M的文件。。。。。

  然后我用记录下的线程ID去里面查,居然一个都没找到。。。。 后面确认了运维发过的来jstack文件有信息缺失。。。。。

然后看到群上一些技术同事说问题可能是调用IT部门的会员卡查询突然变慢了,响应时间由几十ms变成5s,导致了线程数堆积。这里说一下这个IT部门是我们集团里面的一个老部门和我们部门是独立的,我所在的部门是互联网这一块,IT部门相对来就是传统的那种。IT的系统都是外包来做的,性能真的不敢恭维,已知某个系统的qps是3, 所以技术水平自己脑补。当时我看了一下cat监控,确实有很多查IT会员卡的超时告警,但这个情况是一直都存在的,以前却不会出现这种情况。并且负责会员卡的用户组同事说:他们已经对IT的接口加了限流,如果超时太多,就会限制调用IT的接口的次数,线程堆积的情况应该是不存在的。当时分析了一下就算有很多这种等待io的线程,其现象也应该是load高,但cpu占用率应该不是会太高的。这种cpu高和load高的情况一种很常见的情况就是频繁的GC。我于是再回到cat上面去看监控指标,点heartbeat这一栏。对比各项指标,果然间发现GC的时间和次数在10点的时候突然变多了。

  嗯,问题应该是确认了。我于是在有问题机器查找对应的GC日志:

 [GC (Allocation Failure) [PSYoungGen: 1321555K->7203K(1354752K)] 2182429K->881391K(4151296K), 0.0216324 secs] [Times: user=0.08 sys=0.00, real=0.02 secs]
[GC (Allocation Failure) [PSYoungGen: 1317411K->6176K(1353216K)] 2191599K->882824K(4149760K), 0.0177299 secs] [Times: user=0.06 sys=0.00, real=0.02 secs]
[GC (Allocation Failure) [PSYoungGen: 1316384K->7255K(1357824K)] 2193032K->885846K(4154368K), 0.0198454 secs] [Times: user=0.07 sys=0.00, real=0.02 secs]
[GC (Allocation Failure) [PSYoungGen: 1323607K->6080K(1356288K)] 2202198K->886357K(4152832K), 0.0194745 secs] [Times: user=0.07 sys=0.00, real=0.02 secs]
[GC (Allocation Failure) [PSYoungGen: 1279980K->117750K(1073152K)] 2366227K->1332344K(3869696K), 0.1398088 secs] [Times: user=0.51 sys=0.00, real=0.14 secs]
[GC (Allocation Failure) [PSYoungGen: 1073142K->94600K(1176576K)] 2287736K->1409135K(3973120K), 0.1220951 secs] [Times: user=0.47 sys=0.00, real=0.13 secs]
[GC (Allocation Failure) [PSYoungGen: 1049992K->105231K(1184256K)] 2364527K->1492688K(3980800K), 0.1323488 secs] [Times: user=0.45 sys=0.00, real=0.13 secs]
[GC (Allocation Failure) [PSYoungGen: 1073935K->111730K(1182208K)] 2461392K->1563948K(3978752K), 0.1109970 secs] [Times: user=0.42 sys=0.00, real=0.11 secs]
[GC (Allocation Failure) [PSYoungGen: 1080434K->81108K(1197568K)] 2532652K->1607799K(3994112K), 0.1113381 secs] [Times: user=0.42 sys=0.00, real=0.11 secs]
[GC (Allocation Failure) [PSYoungGen: 1065684K->79209K(1184768K)] 2592375K->1654630K(3981312K), 0.1410440 secs] [Times: user=0.40 sys=0.00, real=0.14 secs]
[GC (Allocation Failure) [PSYoungGen: 1063785K->75484K(1219584K)] 2639206K->1694154K(4016128K), 0.1043986 secs] [Times: user=0.39 sys=0.00, real=0.10 secs]
[GC (Allocation Failure) [PSYoungGen: 1106652K->71290K(1209344K)] 2725322K->1727044K(4005888K), 0.0994654 secs] [Times: user=0.38 sys=0.00, real=0.10 secs]
[GC (Allocation Failure) [PSYoungGen: 1102458K->74219K(1236480K)] 2758212K->1769216K(4033024K), 0.1000352 secs] [Times: user=0.38 sys=0.00, real=0.10 secs]
[GC (Allocation Failure) [PSYoungGen: 1141227K->74573K(1228288K)] 2836224K->1809430K(4024832K), 0.1089653 secs] [Times: user=0.40 sys=0.00, real=0.11 secs]
[GC (Allocation Failure) [PSYoungGen: 1141581K->70656K(1250816K)] 2876438K->1842238K(4047360K), 0.1406505 secs] [Times: user=0.38 sys=0.00, real=0.14 secs]
[GC (Allocation Failure) [PSYoungGen: 1168384K->95266K(1244672K)] 2939966K->1897805K(4041216K), 0.1442105 secs] [Times: user=0.40 sys=0.00, real=0.14 secs]

  果然看到了过了10点,堆内存的使用突然暴涨,应用在频繁的GC,并且每次GC时间基本都在100ms以上。至于具体是什么原因导致的GC现在还没得知,唯一的办法就是dump出当时内存镜像,遗憾的是当时没有及时的dump下来。CPU占用率高和load高的情况只持续了一分钟时间,运维同事也没有dump下来。

  要找出原因只能从当时的请求来入手,于是我看当时的应用请求情况。发现GC的的时间点还真的和会员卡的请求突然大量增加和超时基本吻合,于是我来拉下会员卡项目的代码选了其中的会员卡列表和微信卡包列表等相关接口来看一下,还真的发现了一些的问题。其中比较重要的一个是:如果客户端没传分页传参数进来程序就会load用户所有数据出去,之前听说某些用户下面有1000多张会员卡。然后我去看了请求日志发现微信卡包列表的所有请求都没有传分页参数进来,客户端某些版本没有传。并且会员卡列表和微信卡包列表当请求量是平时的几十倍。load用户全部数据,请求量大,这种情况引起GC的概率确实比较大。后面我把了解的情况反馈给了用户组的同事。

  总结一下整个过程:从告警到问题定位,中间的几个点其实是可以改进的。

  1、jstack文件信息大多,但关键信息却丢失了。原因是jstack是10秒钟才记录一次,所以我记录下来的线程ID和运维给的文件里面的信息里面并不一定对得上。运维同事最好可以提供一下实时工具保留当时的第一手信息。另外如果有什么好用的工具欢迎推荐~。

  2、监控不到位。会员卡用的限流组件是阿里最新开源的Sentinel,采用的qps限流并不是线程数限流。所以当时并不知道会员卡相关到底吃了系统多少线程。对于限流组件这块我个人是比较推荐hystrix,因为功能比较齐全,开源时间长,很多坑别人都已经踩过了。阿里的Sentinel刚出来应该很多点还需要完善。另外一点就是GC内存的文件没有及时dump下来。

  3、代码规范和code-view。最好接入一些代码检查工具比如sonar,及时找出程序里面一些坑。一些热点代码最好组织一下code-view,这些也可以避免很多线上问题。

  

记一次CPU占用率和load高的排查的更多相关文章

  1. 记一次线上Java程序导致服务器CPU占用率过高的问题排除过程

    博文转至:http://www.jianshu.com/p/3667157d63bb,转本博文的目的就是需要的时候以防忘记 1.故障现象 客服同事反馈平台系统运行缓慢,网页卡顿严重,多次重启系统后问题 ...

  2. 线上Java程序导致服务器CPU占用率过高的问题排除过程

    博文转至:http://www.jianshu.com/p/3667157d63bb,博文更好效果看原版,转本博文的目的就算是个书签吧,需要时候可以定位原文学习 1.故障现象 客服同事反馈平台系统运行 ...

  3. 一次服务器CPU占用率高的定位分析

    现象: 当前项目启动一段时间,有一个服务导致CPU使用率持续超过30% 环境:Windows 7,  CPU: 8核, 内存: 8g内存 定位过程: 启动项目,查看Java进程ID 查看Event P ...

  4. [原]调试实战——程序CPU占用率飙升,你知道如何快速定位吗?

    原调试debugwindbghangprocess explorer 前言 如果我们自己的程序的CPU Usage(CPU占用率)飙升,并且居高不下,很有可能陷入了死循环.你知道怎么快速定位并解决吗? ...

  5. Linux下如何查看高CPU占用率线程

    转于:http://www.cnblogs.com/lidabo/p/4738113.html 目录(?)[-] proc文件系统 proccpuinfo文件 procstat文件 procpidst ...

  6. Linux下如何查看高CPU占用率线程 LINUX CPU利用率计算

    目录(?)[-] proc文件系统 proccpuinfo文件 procstat文件 procpidstat文件 procpidtasktidstat文件 系统中有关进程cpu使用率的常用命令 ps ...

  7. Linux下java进程CPU占用率高分析方法

    Linux下java进程CPU占用率高分析方法 在工作当中,肯定会遇到由代码所导致的高CPU耗用以及内存溢出的情况.这种情况发生时,我们怎么去找出原因并解决. 一般解决方法是通过top命令找出消耗资源 ...

  8. linux top命令中各cpu占用率含义

    linux top命令中各cpu占用率含义 [尊重原创文章摘自:http://www.iteye.com/topic/1137848]0.3% us 用户空间占用CPU百分比 1.0% sy 内核空间 ...

  9. 编程之美_1.1 让CPU占用率曲线听你指挥

    听到有人说让要写一个程序,让用户来决定Windows任务管理器的CPU占用率. 觉得很好奇.但第一个想法就是写个死循环.哈哈.不知道具体的占用率是多少,但至少能保证在程序运行时,CPU的占用率终会稳定 ...

随机推荐

  1. BZOJ:1816 [Cqoi2010]扑克牌 (贪心或二分答案)

    题面 \(solution:\) 这道题难就难在你能否读懂题目的意思,我们将它翻译一下: 现在我有n根竹子(每根竹子有\(c_i\)节,每节竹子高度为1),我可以通过消耗一点法力值使某一根竹子的某两节 ...

  2. 【centos】 error: command 'gcc' failed with exit status 1

    原文连接http://blog.csdn.net/fenglifeng1987/article/details/38057193 用安装Python模块出现error: command 'gcc' f ...

  3. mysql 原理 ~ 二阶段提交协议通说

    一 简介: 今天是第二篇,讲解的是mysql的事务日志 二 具体 1 WAL技术(先写日志,再写磁盘) 2 binlog redolog 二阶段提交协议     目的 保持 redo log和binl ...

  4. CentOS6.5优化脚本以及检测优化脚本

    一.tunning.sh #!/bin/bash # 系统优化脚本 # 使用于CentOS 6.4 x64系统 # Ver : 1.1.1 KCF=/etc/sysctl.conf # ------- ...

  5. 一步步实现windows版ijkplayer系列文章之六——SDL2源码分析之OpenGL ES在windows上的渲染过程

    一步步实现windows版ijkplayer系列文章之一--Windows10平台编译ffmpeg 4.0.2,生成ffplay 一步步实现windows版ijkplayer系列文章之二--Ijkpl ...

  6. 006_ssl监测及评分

    https://testssl.sh/ 一. https://www.ssllabs.com/ssltest/analyze.html?d=jyall.com 监测下jyll.com,不忍直视啊! 二 ...

  7. centos 6.5环境利用iscsi搭建SAN网络存储服务及服务端target和客户端initiator配置详解

    一.简介 iSCSI(internet SCSI)技术由IBM公司研究开发,是一个供硬件设备使用的.可以在IP协议的上层运行的SCSI指令集,这种指令集合可以实现在IP网络上运行SCSI协议,使其能够 ...

  8. HDU 5288 OO’s Sequence

    题意: 给你一个序列, 有一个函数 F(L,R) 其中 ai 均不能 被 aL - aR整除的  函数值是这个ai个数 思路 : 反过来求 满足这样的条件的 ai 的区间,然后求和 #include& ...

  9. python读取两个csv文件数据,进行查找匹配出现次数

    现有需求 表1 表2 需要拿表1中的编码去表2中的门票编码列匹配,统计出现的次数,由于表2编码列是区域间,而且列不是固定的,代码如下 #encoding:utf-8 ##导入两个CSV进行比对 imp ...

  10. Python-垃圾回收机制

    引子: 我们定义变量会申请内存空间来存放变量的值,而内存的容量是有限的,当一个变量值没有用了(简称垃圾)就应该将其占用的内存给回收掉,而变量名是访问到变量值的唯一方式,所以当一个变量值没有关联任何变量 ...