死锁问题排查

初步判断

某个服务在启动时线程数量会越来越多,可以在Venus中查看,并收到通知:

xx

如果观察服务的请求处理量,发现并没有增加,因此判断 服务出现死锁了!



抓dump包


具体过程可参考:抓dump包



用VS分析dump包

用VS打开dump文件,并点击链接

xx

观察每个线程当时在做什么

xx

很明显,大多数线程卡在 SendMessage 方法的 lock 语句上。

出现这个问题,一般可以肯定:至少有一个线程已进入 lock 语句块。
此时注意看VS给出的提示:

xx

找到 141 号线程,此时发现进入 lock 的线程在这里。

xx



另一种方法确认

用 dotnet-dump 来分析 dump 文件。

dotnet-dump analyze  "E:\Temp\dump\新建文件夹\DataCenterApp.dmp"

查看进程中的所有锁对象:

syncblk

xx

很明显,有大量的线程阻塞在这个锁对象上。

再来查看持有锁的线程在做什么:

> setthread 64
> clrstack

xx

此时可以看到比VS更完整的线程堆栈信息。



这里补充说明下syncblk的结果中如何得到线程ID

xx

00007FD26104EFE0 8d  64

这3个列其实都是线程信息,只不过是3种表示方式而已。

可以执行 clrthreads 命令来查看:

xx

(十六进制)8D == (十进制)141,VS中显示的就是线程141




分析&结论

  1. 发送Rabbit消息放在Action中执行,
  2. 当第一个Action线程在打开Rabbit连接时,ASP.NET 接收了大量的HTTP请求,此时消耗了大量的线程,
  3. 打开Rabbit连接时,至少需要消耗3个线程,导致这个操作一直没有机会完成
  4. 后面越来越多的HTTP请求进入,Rabbit连接永远无法打开,造成程序卡死。