我们有一个托管在 azure 应用服务中的 ASP.NET MVC 应用程序。运行探查器来帮助诊断可能的缓慢请求后,我们惊讶地发现:
CLRThreadPoolQueue 中缓慢请求的百分比异常高。现在,我们已经运行了多个配置文件 session ,每个 session 返回的 CLRThreadPoolQueue 中的资源量都在 40-80% 之间(这是我们在之前的配置文件中从未见过的)。 CPU 每次都低于 40%,在检查我们的指标后,我们没有遇到请求突然激增的情况。
列出的大多数慢速请求都是 super 简单的 API 调用。我们添加了响应缓存并使它们异步。他们唯一做的就是访问数据库寻找单个记录结果。我们检查了数据库的指标,查询平均运行时间约为 50 毫秒或更短。查看这些请求的应用程序见解证实了这一点,并显示数据库查询直到请求时间线的最后才发生(我假设这是队列中的请求)。
最近我们开始将 SignalR 纳入我们应用程序的一部分。它尚未完全使用,但已在代码库中。此后,我们改用 Azure SignalR 服务,但没有看到任何变化。添加 SignalR 是我们自遇到此问题以来所做的唯一“重大”更改/添加。
我知道我们可以扩大和/或增加 minWorkerThreads。然而,这感觉就像我只是治标不治本。
我们尝试过的事情:
- 查找最频繁的请求并使它们异步(以前不是)
- 对频繁请求的响应缓存
- 使用 Azure SignalR 服务,而不是将其托管在同一网络上
- 运行内存转储并联系 azure 支持(他们 什么也没找到)。
- 扩展到 S3
- 使用和不使用线程报告进行分析
-- 这些步骤都没有解决我们的问题 --
我们如何确定哪些请求和/或代码导致请求堆积在 CLRThreadPoolQueue 中?
最佳答案
我们遇到了类似的问题,我猜 SignalR 内部一定使用了大量线程或其他一些竞争资源。
我们做了三件很有帮助的事情:
在应用启动时调用
ThreadPool.SetMinThreads(400, 1)
以确保线程池有足够的线程来处理从一开始的所有传入请求创建第二个应用服务并部署相同的代码。在 javascript 中,将 SignalR URL 设置为指向第二个实例。这样,所有 SignalR 请求都会发送到一个应用程序服务,而应用程序的所有 HTTP 请求都会发送到另一个应用程序服务。显然,这需要设置 SignalR 背板,但假设您的应用服务有超过 1 个实例,您无论如何都必须执行此操作
检查任何同步代码路径的代码(例如,对数据库或 API 进行非异步调用)并将其转换为异步代码路径
关于asp.net-mvc - CLRThreadPoolQueue 中的大部分请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60402708/