IIS ASP.NET WebApi请求同一服务器时死锁

12

我们在同一台IIS服务器上使用互连的ASP.NET WebApi时遇到了一些死锁问题。我们想知道这是否是因为将所有API都托管在同一台服务器和同一应用程序池中而导致的预期行为,因为我们已经通过将任一WebApi移动到不同的池中来避免此问题;或者我们的代码有问题。

对于生产,我们可能会将API托管在不同的服务器或池中,但我们仍然希望了解为什么会发生这种情况。我们主要担心的是,如果是我们的有故障代码,即使托管设置正确,问题也可能在较大规模上得到复制。

我们创建了一个小型解决方案来重现死锁,托管在GitHub上

重现步骤如下:

  1. WebClient并行执行多个HTTP请求至WebApi1。
  2. WebApi1对WebApi2执行HTTP请求。
  3. WebApi2对WebApi3执行HTTP请求。
  4. WebApi3只返回一个字符串。

预期行为是所有请求最终都被解决。

实际行为是某些请求完成,而其他一些请求将失败,由于TaskCancelledException,这似乎是由于请求超时引起的。

我能找到的唯一一篇提到相同问题的文章是2014年的:"不要将 ServerXMLHTTP 或 WinHTTP 请求发送到同一服务器",我相信这就是我们正在经历的问题,如何确认这一点?

背景

我们被分配任务为公司内部多个API创建一个集中式身份验证服务器。 我们使用IdentityServer3和参考令牌,因此当某个API使用参考令牌请求第二个API时,第二个API将请求身份验证服务器进行令牌验证,从而重现了该问题。

我已添加IdentityServer标签,因为在进行多个API通信并使用引用令牌时,这可能是一个常见问题。GitHub上的示例


2
我们怎样才能确认这个问题呢?或许可以将它们分别运行在不同的池中,然后检查问题是否仍然存在? - vtortola
1
我想查看一些日志,以了解可能出现死锁的原因。在启动时尝试加载元数据时是否有死锁?您是否尝试过使用 DelayLoadMetadata 标志?https://identityserver.github.io/Documentation/docsv2/consuming/options.html - Brock Allen
1
也许你正在触及IIS的限制?https://blogs.msdn.microsoft.com/benjaminperkins/2011/11/14/modify-the-request-queue-limit-requestqueuelimit-or-queue-length-in-iis-7/ - John Korsnes
1
WinHTTP的文章是针对非托管世界的。然而,在.NET中也有同样类型的默认限制(实际上这来自于HTTP标准)。您可以尝试在Web服务器启动代码中将ServicePointManager.DefaultConnectionLimit设置为1000或其他值。https://msdn.microsoft.com/en-us/library/office/system.net.servicepointmanager.defaultconnectionlimit - Simon Mourier
1
这是一个在Windows 10上到处都是的相当标准的DefaultWebSite中的DefaultAppPool。 - Simon Mourier
显示剩余9条评论
1个回答

1

仅有一点观察:您正在将HttpClient作为每个控制器的静态成员使用,而根据this HttpClient不能保证是线程安全的。


嗨,Dave,我在MSDN上找到了一篇文章,他们建议创建一个单独的HttpClient并进行重用。我们已经尝试过使用using语句来创建单个实例,但没有任何变化。 - Leonardo Chaia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接