死锁问题排查
初步判断
某个服务在启动时线程数量会越来越多,可以在Venus中查看,并收到通知:
如果观察服务的请求处理量,发现并没有增加,因此判断 服务出现死锁了!
抓dump包
具体过程可参考:抓dump包
用VS分析dump包
用VS打开dump文件,并点击链接
观察每个线程当时在做什么
很明显,大多数线程卡在 SendMessage 方法的 lock 语句上。
出现这个问题,一般可以肯定:至少有一个线程已进入 lock 语句块。
此时注意看VS给出的提示:
找到 141 号线程,此时发现进入 lock 的线程在这里。
另一种方法确认
用 dotnet-dump 来分析 dump 文件。
dotnet-dump analyze "E:\Temp\dump\新建文件夹\DataCenterApp.dmp"
查看进程中的所有锁对象:
syncblk
很明显,有大量的线程阻塞在这个锁对象上。
再来查看持有锁的线程在做什么:
> setthread 64
> clrstack
此时可以看到比VS更完整的线程堆栈信息。
这里补充说明下syncblk的结果中如何得到线程ID
00007FD26104EFE0 8d 64
这3个列其实都是线程信息,只不过是3种表示方式而已。
可以执行 clrthreads 命令来查看:
(十六进制)8D == (十进制)141,VS中显示的就是线程141
分析&结论
- 发送Rabbit消息放在Action中执行,
- 当第一个Action线程在打开Rabbit连接时,ASP.NET 接收了大量的HTTP请求,此时消耗了大量的线程,
- 打开Rabbit连接时,至少需要消耗3个线程,导致这个操作一直没有机会完成
- 后面越来越多的HTTP请求进入,Rabbit连接永远无法打开,造成程序卡死。