生产环境服务CPU高问题分析
问题描述:
现网个别时候会出现CPU突然飙高的现象,飙高后不能恢复正常。
分析过程:
CPU飙高后抓dump,最好本机看,其它机器看dump可能需要下载服务运行机器的sos,clr
0:000> !threadpool
The version of SOS does not match the version of CLR you are debugging. Please
load the matching version of SOS for the version of CLR you are debugging.
CLR Version: 4.0.30319.276
SOS Version: 4.0.30319.17929
CPU utilization: 100%
Worker Thread: Total: 54 Running: 54 Idle: 0 MaxLimit: 32767 MinLimit: 8
Work Request in Queue: 0
--------------------------------------
Number of Timers: 3
--------------------------------------
Completion Port Thread:Total: 10 Free: 10 MaxFree: 16 CurrentLimit: 8 MaxLimit: 1000 MinLimit: 8
CPU确实高,54个线程都在跑着。
接着看线程都在干什么
0:000> ~*e!clrstack
OS Thread Id: 0x3278 (57)
Child SP IP Call Site
000000000c72cea8 0000000077ef047a [RedirectedThreadFrame: 000000000c72cea8]
000000000c72cf40 000006448056c07e ********************.
SecurityQuota.ConcurrentLinkedQueue`1[[System.__Canon, mscorlib]].TryDequeue(System.__Canon ByRef)
000000000c72cff0 00000644805999e8 ********************.SecurityQuota.SecurityFeatureDigest.GetIncrementalDigest(********************)
……

有50个线程在做该操作,review该处代码
为了防止本地代码和服务器不一致,直接反编译的服务器的代码,GetIncrementalDigest方法如下
public class SecurityFeatureDigest : ISecurityFeatureDigest
{
// Fields
private static Database _data = DatabaseManager.GetDatabase("SQSDB");
private static readonly ITracing _tracer = TracingManager.GetTracing(typeof(SecurityFeatureDigest));
private static ConcurrentLinkedQueue<List<FeatureDigest>> queue =
new ConcurrentLinkedQueue<List<FeatureDigest>>(new List<FeatureDigest>()); (2)
private static readonly string[] SetFeatureDigestParameter = new string[] { "@digest", "@operation", "@sample", "@stamp" };
// 略…
public void GetIncrementalDigest(RpcServerContext context)
{
DateTime args = context.GetArgs<DateTime>();
List<FeatureDigest> results = new List<FeatureDigest>();
List<FeatureDigest> result = null;
while (true)
{
if (queue.TryDequeue(out result)) (1)
{
List<FeatureDigest> list3 = new List<FeatureDigest>();
list3.AddRange(result);
queue.Enqueue(result);
foreach (FeatureDigest digest in list3)
{
if (digest.Version > args)
{
digest.Sample = string.Empty;
results.Add(digest);
}
}
context.Return<List<FeatureDigest>>(results);
return;
}
}
}
// 略…
}
从抓的dump看,极有可能是死循环了。通过以上代码看到,如果(1)处的返回为false的话,则改段代码会陷入死循环。接着看下什么情况下返回false。
public class ConcurrentLinkedQueue<T>
{
// Fields
private Node<T, T> _head;
private Node<T, T> _tail;
// 略…
public bool TryDequeue(out T result)
{
while (true)
{
Node<T, T> comparand = this._head;
Node<T, T> node2 = this._tail;
Node<T, T> next = comparand.Next;
if (comparand == this._head)
{
if (next == null) (3)
{
result = default(T);
return false;
}
if (comparand == node2)
{
Interlocked.CompareExchange<Node<T, T>>(ref this._tail, next, node2);
}
else
{
result = next.Item;
if (Interlocked.CompareExchange<Node<T, T>>(ref this._head, next, comparand) == comparand)
{
break;
}
}
}
}
return true;
}
从(3)处可以看出,如果head的next为null的话,则返回false。为了确认分析是否正确,看下此处的值是不是null
0:000> !dumpheap -stat
Statistics:
MT Count TotalSize Class Name
000006448054b2d0 1 32 ********************.SecurityQuota.ConcurrentLinkedQueue`1
[[System.Collections.Generic.List`1[[********************.FeatureDigest, IICSecurityLibrary]], mscorlib]]
0:000> !dumpheap – -mt 000006448054b2d0
------------------------------
Heap 6
Address MT Size
00000001404836f0 000006448054b2d0 32
total 0 objects
Statistics:
MT Count TotalSize Class Name
32 ********************.SecurityQuota.ConcurrentLinkedQueue`1
[[System.Collections.Generic.List`1[[********************.FeatureDigest, *****]], mscorlib]]
Total 1 objects
0:000> !do 00000001404836f0
Name: ********************.SecurityQuota.ConcurrentLinkedQueue`1[[System.Collections.Generic.List`1
[[********************.FeatureDigest, *****]], mscorlib]]
MethodTable: 000006448054b2d0
EEClass: 0000064480557a90
Size: 32(0x20) bytes
File: ********************\SecurityQuotaService.exe
Fields:
MT Field Offset Type VT Attr Value Name
8 ...Canon, mscorlib]] 0 instance 00000000c3135ec8 _head
10 ...Canon, mscorlib]] 0 instance 00000000c3135ec8 _tail
0:000> !do 00000000c3135ec8
Name: ********************.SecurityQuota.ConcurrentLinkedQueue`1+Node`1[[System.Collections.Generic.List`1[[********************.
FeatureDigest, *****]], mscorlib],[System.Collections.Generic.List`1[[********************.FeatureDigest, *****]], mscorlib]]
MethodTable: 000006448054b7f8
EEClass: 00000644805580b8
Size: 32(0x20) bytes
File: ********************\SecurityQuotaService.exe
Fields:
MT Field Offset Type VT Attr Value Name
8 System.__Canon 0 instance 00000001404836a8 Item
10 ...Canon, mscorlib]] 0 instance 0000000000000000 Next
发现Next为null
问题结论:
由于一些异常逻辑导致程序死循环,此处代码也有问题,对异常逻辑处理不够。
作者:No.40
Blog:http://www.cnblogs.com/no40
生产环境服务CPU高问题分析的更多相关文章
- 生产环境如何快速跟踪、分析、定位问题-Java
我相信做技术的都会遇到过这样的问题,生产环境服务遇到宕机的情况下如何去分析问题?比如说JVM内存爆掉.CPU持续高位运行.线程被夯住或线程deadlocks,面对这样的问题,如何在生产环境第一时间跟踪 ...
- Db2性能:系统CPU高问题分析的一些思路
Db2性能:系统CPU高问题分析的一些思路 1. 如何判断CPU高? 有很多操作系统的命令可以看出来,比如ps -elf,iostat, vmstat, top/topas, 2. 收集数据 CPU高 ...
- 生产环境JAVA进程高CPU占用故障排查
问题描述:生产环境下的某台tomcat7服务器,在刚发布时的时候一切都很正常,在运行一段时间后就出现CPU占用很高的问题,基本上是负载一天比一天高. 问题分析:1,程序属于CPU密集型,和开发沟通过, ...
- K8S生产环境中实践高可靠的配置和技巧都有哪些?
K8S环境中实践高可靠的配置和技巧都有哪些? 磁盘类型及大小 磁盘类型: 推荐使用ssd 磁盘 对于worker节点,创建集群时推荐使用挂载数据盘.这个盘是专门给/var/lib/docker 存放本 ...
- 【转】生产环境:Nginx高可用方案
准备工作: 192.168.16.128 192.168.16.129 两条虚拟机.安装好 Nginx 安装Nginx 更新 yum 源文件: rpm -ivh http://nginx.org/pa ...
- 生产环境之Nginx高可用方案
准备工作: 192.168.16.128 192.168.16.129 两台虚拟机.安装好Nginx 安装Nginx 更新yum源文件: rpm -ivh http://nginx.org/packa ...
- linux安装Django 以及 生产环境部署实现高并发
1.首先安装python Python编译安装 主要介绍linux环境下安装 cd /usr/local/src //进入安装目录 wget https://www.python.org/ ...
- java面试-生产环境出现CPU占用过高,谈谈你的分析思路和定位
思路:结合Linux和JDK命令一起分析 1.用top命令找出CPU占比最高的进程 2.ps -ef|grep java|grep -v grep 或者jps -l进一步定位,得知是怎样一个后台程序惹 ...
- 转 cpu高 问题分析定位
文章来源: http://www.blogjava.net/hankchen/archive/2012/08/09/377735.html 一个应用占用CPU很高,除了确实是计算密集型应用之外,通常原 ...
随机推荐
- *在Win7中安装JDK1.7并配置环境变量
安装的过程就不废话了. 下面是环境变量的配置. 1. 配置环境变量 单机右键‘计算机--属性’ 2.点击高级系统设置 3.点击‘环境变量’ 4.增加"JAVA_HOME"系统变 ...
- Linux系统管道命令符
管道命令符“|”的作用是将前一个命令的标准输出作为后一个命令的标准输入,格式为“命令A | 命令B” 以下实例中,通过grep命令搜索关键字“/sbin/nologin”在/etc/passwd中查找 ...
- istream, outstream使用及常见错误
使用方法: 使用filebuf打开文件,并拷贝给istream/ostream. 如下面的例子中,实现读取并处理deseq文件夹下所有文件,输出到ostream fw. code: #include& ...
- linux系统的文件和文件类型
文件 当你创建一个文件的时候,系统保存了有关该文件的全部信息,包括:• 文件的位置.• 文件类型.• 文件长度.• 哪位用户拥有该文件,哪些用户可以访问该文件.• i节点.• 文件的修改时间.• 文件 ...
- 【转】Android 使用ORMLite 操作数据库
Android 使用ORMLite 操作数据库 用过ssh,s2sh的肯定不会陌生 ,应该一学就会 第一步: 下载ormlite-android-4.41.jar和ormlite-core-4.4 ...
- [ionic开源项目教程] - 第4讲 通Service层获取数据列表
第4讲:通Service层获取数据列表 上一讲中页面的基本架构已完成,这一讲介绍如何通过service层从服务器请求数据,在通过controller层为载体,显示到视图层. 1.在services.j ...
- UVa 11014 (莫比乌斯反演) Make a Crystal
这个题是根据某个二维平面的题改编过来的. 首先把问题转化一下, 就是你站在原点(0, 0, 0)能看到多少格点. 答案分为三个部分: 八个象限里的格点,即 gcd(x, y, z) = 1,且xyz均 ...
- UVa 1595 (水题) Symmetry
颓废的一个下午,一直在切水题,(ˉ▽ ̄-) 首先如果这些点是对称的话,那么它们的对称轴就是x = m,m是横坐标的平均值. 把这些点放到一个集合里,然后扫描每个点,计算出它关于x = m的对称点,看这 ...
- 51nod1403 有趣的堆栈
看成括号序列的话第二种方法其实就是左括号和右括号之间有多少对完整的括号. #include<cstdio> #include<cstring> #include<ccty ...
- 配置域名服务器报错named[822]: dns_rdata_fromtext /etc/bind/db.asertest.com mail not a valid number
问题描述: 为了配置邮件服务器,更改了相关域名,改完后,重启bind9报错 Mar 17 14:39:39 DnsServer2 named[822]: dns_rdata_fromtext: /et ...