问题描述:

现网个别时候会出现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高问题分析的更多相关文章

  1. 生产环境如何快速跟踪、分析、定位问题-Java

    我相信做技术的都会遇到过这样的问题,生产环境服务遇到宕机的情况下如何去分析问题?比如说JVM内存爆掉.CPU持续高位运行.线程被夯住或线程deadlocks,面对这样的问题,如何在生产环境第一时间跟踪 ...

  2. Db2性能:系统CPU高问题分析的一些思路

    Db2性能:系统CPU高问题分析的一些思路 1. 如何判断CPU高? 有很多操作系统的命令可以看出来,比如ps -elf,iostat, vmstat, top/topas, 2. 收集数据 CPU高 ...

  3. 生产环境JAVA进程高CPU占用故障排查

    问题描述:生产环境下的某台tomcat7服务器,在刚发布时的时候一切都很正常,在运行一段时间后就出现CPU占用很高的问题,基本上是负载一天比一天高. 问题分析:1,程序属于CPU密集型,和开发沟通过, ...

  4. K8S生产环境中实践高可靠的配置和技巧都有哪些?

    K8S环境中实践高可靠的配置和技巧都有哪些? 磁盘类型及大小 磁盘类型: 推荐使用ssd 磁盘 对于worker节点,创建集群时推荐使用挂载数据盘.这个盘是专门给/var/lib/docker 存放本 ...

  5. 【转】生产环境:Nginx高可用方案

    准备工作: 192.168.16.128 192.168.16.129 两条虚拟机.安装好 Nginx 安装Nginx 更新 yum 源文件: rpm -ivh http://nginx.org/pa ...

  6. 生产环境之Nginx高可用方案

    准备工作: 192.168.16.128 192.168.16.129 两台虚拟机.安装好Nginx 安装Nginx 更新yum源文件: rpm -ivh http://nginx.org/packa ...

  7. linux安装Django 以及 生产环境部署实现高并发

    1.首先安装python Python编译安装 主要介绍linux环境下安装 cd  /usr/local/src     //进入安装目录 wget  https://www.python.org/ ...

  8. java面试-生产环境出现CPU占用过高,谈谈你的分析思路和定位

    思路:结合Linux和JDK命令一起分析 1.用top命令找出CPU占比最高的进程 2.ps -ef|grep java|grep -v grep 或者jps -l进一步定位,得知是怎样一个后台程序惹 ...

  9. 转 cpu高 问题分析定位

    文章来源: http://www.blogjava.net/hankchen/archive/2012/08/09/377735.html 一个应用占用CPU很高,除了确实是计算密集型应用之外,通常原 ...

随机推荐

  1. Struts2笔记——类型转换

     概述 * 从一个HTML 表单到一个Action 对象, 类型转换是从字符串到非字符串.     >HTTP 没有 “类型” 的概念. 每一项表单输入只可能是一个字符串或一个字符串数组. 在服 ...

  2. DWR与AJAX

    DWR与AJAX的微妙关系 2015-08-14 10:20 447人阅读 评论(0) 收藏 举报 本文章已收录于:   // ' + obj.name + "  "; html ...

  3. 8天学通MongoDB

    随笔分类 - MongoDB 双十一来了,别让你的mongodb宕机了 摘要: 好久没过来吹牛了,前段时间一直赶项目,没有时间来更新博客,项目也终于赶完了,接下来就要面临双十一这场惊心动魄的处女秀考验 ...

  4. Xlib: connection to ":0.0" refused by server Xlib: No protocol specified解决方案

    Xlib: connection to ":0.0" refused by server Xlib:  No protocol specified 解决办法: 1. 退出oracl ...

  5. JavaScript —— attachEvent 方法的使用

    动态地给一个对象添加事件(方法). 直接上代码: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" ...

  6. css div居中显示的4种写法

    Demo:http://www.feman.cn/h5/center.html .absolute 绝对定位 这是我们最常用的一种居中定位写法 要求必须确定div的宽高度 目前市面上的浏览器基本上都支 ...

  7. 数据库系统中事务的ACID原则

    事务的原子性.一致性.独立性及持久性 事务的原子性是指一个事务要么全部执行,要么不执行.也就是说一个事务不可能只执行了一半就停止了.比如你从取款机取钱,这个事务可以分成两个步骤:1划卡,2出钱.不可能 ...

  8. Post的请求案例

    1.简单的post请求案例 $.post(rootPath+"/jasframework/loginLog/getStatisticsInfoByUserId.do",functi ...

  9. Asp.net Web Api进行Nunit测试

    有两种方式 1.模拟Web请求. 2.直接本地调用Api接口 但是由于本地直接调用没有模拟请求环境,所以request为null public static HttpResponseMessage C ...

  10. 使用MySQL Proxy解决MySQL主从同步延迟

    MySQL的主从同步机制非常方便的解决了高并发读的应用需求,给Web方面开发带来了极大的便利.但这种方式有个比较大的缺陷在于MySQL的同步机制 是依赖Slave主动向Master发请求来获取数据的, ...