大概有2个月没写博客了,不是不想写哈??,关注公号的朋友应该知道我这两个月一直都在翻译文章,前前后后大概100篇左右吧,前几天看公号的 常读用户 降了好几十,心疼哈,还得回过神来继续写!
2. 讲故事
上周给 武汉同济 做项目升级,本以为一切顺利,结果捅娄子了,第二天上午高峰期运维说生产上两台 应用服务器 cpu 被打满,影响到所有客户使用,造成了大面积瘫痪,真尬尴,得先让运维抓一个 dump 下来再重启网站,还好,老板人可以,没有问责 ??。
二:CPU 爆高问题分析
1. 找思路
分析 dump,没什么比 windbg 更专业了,不过分析 dump 我还是比较拿手的,那怎么分析呢?最简单粗暴的做法就是看每一个线程当时都在做什么,进而推测一下就 八九不离十 了。
2. 查看所有线程栈
首先用 !t 和 !tp 看一下当前程序的 线程 和 线程池 的整体概况。
- 0:000> !t
- ThreadCount: 60
- UnstartedThread: 0
- BackgroundThread: 38
- PendingThread: 0
- DeadThread: 22
- Hosted Runtime: no
- Lock
- ID OSID ThreadOBJ State GC Mode GC Alloc Context Domain nc">Count Apt Exception
- 11 1 2c24 02487038 28220 Preemptive 00000000:00000000 010df4f8 0 Ukn
- 28 2 2ca0 024bad90 2b220 Preemptive 00000000:00000000 010df4f8 0 MTA (Finalizer)
- 30 3 2d04 024f1450 102a220 Preemptive 00000000:00000000 010df4f8 0 MTA (Threadpool Worker)
- 31 4 2054 024fb188 21220 Preemptive 00000000:00000000 010df4f8 0 Ukn
- 32 6 1128 02574400 1020220 Preemptive 00000000:00000000 010df4f8 0 Ukn (Threadpool Worker)
- 2 5 27ac 02520da8 20220 Preemptive 00000000:00000000 010df4f8 0 Ukn
- 35 17 2c44 1cc362c8 202b220 Preemptive 00000000:00000000 024fa838 1 MTA
- 36 20 1740 1cccc748 21220 Preemptive 00000000:00000000 010df4f8 0 Ukn
- 37 21 16c4 1cc08240 21220 Preemptive 00000000:00000000 010df4f8 0 Ukn
- 38 22 16a8 1ccd28b8 21220 Preemptive 00000000:00000000 010df4f8 0 Ukn
- ….
- 0:000> !tp
- CPU utilization: 97%
- Worker Thread: Total: 21 Running: 21 Idle: 0 MaxLimit: 8191 MinLimit: 8
- Work Request in Queue: 23
- Unknown Function: 6d92a17f Context: 0109b5f0
- Unknown Function: 6d92a17f Context: 0107ed90
- Unknown Function: 6d92a17f Context: 0104e750
- Unknown Function: 6d92a17f Context: 010a0200
- AsyncTimerCallbackCompletion TimerInfo@207f8008
- AsyncTimerCallbackCompletion TimerInfo@0251b418
- Unknown Function: 6d92a17f Context: 01096c78
- Unknown Function: 6d92a17f Context: 01081398
- AsyncTimerCallbackCompletion TimerInfo@024d0120
- Unknown Function: 6d92a17f Context: 010a9a20
- Unknown Function: 6d92a17f Context: 01057950
- Unknown Function: 6d92a17f Context: 0104c2d0
- Unknown Function: 6d92a17f Context: 010943d8
- Unknown Function: 6d92a17f Context: 0107a180
- Unknown Function: 6d92a17f Context: 010a7418
- Unknown Function: 6d92a17f Context: 010839a0
- Unknown Function: 6d92a17f Context: 010678d0
- Unknown Function: 6d92a17f Context: 010a2808
- Unknown Function: 6d92a17f Context: 0105c250
- Unknown Function: 6d92a17f Context: 0108abb8
- Unknown Function: 6d92a17f Context: 0108f7c8
- Unknown Function: 6d92a17f Context: 0108d1c0
- Unknown Function: 6d92a17f Context: 20896498
- ————————————–
- Number of Timers: 0
- ————————————–
- Completion Port Thread:Total: 1 Free: 1 MaxFree: 16 CurrentLimit: 1 MaxLimit: 1000 MinLimit: 8
从上面的输出大概可以看到如下几点信息:
- 当前程序有 60 个线程。
- 当前 CPU 利用率为 97%,爆高无疑。
- 线程池中有21个线程全部打满,还有23个任务在 任务队列 中排队等待处理。
总的来看,系统已经高负荷,不堪重负了,接下来的一个疑问就来了,所有的线程都被打满而且线程池中还有大量等待处理的任务在排队,现有的线程都在干嘛呢?难道不处理吗?