ADO.NET 池化连接无法重用

ADO.NET Pooled connections are unable to reuse

我正在开发一个 ASP.NET MVC 应用程序,它使用 EF 6.x 来处理我的 Azure SDL 数据库。最近随着负载的增加,应用程序开始进入无法再与 SQL 服务器通信的状态。我可以看到使用 exec sp_who 有 100 个活动连接到我的数据库,并且无法创建任何新连接并出现以下错误:

System.Data.Entity.Core.EntityException: The underlying provider failed on Open. ---> System.InvalidOperationException: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because of all pooled connections were in use and max pool size was reached.

大部分时间,应用程序的平均活动连接数为 10 到 20。并且任何负载都不会改变此数字...当负载较高时,事件会保持在 10-20 级别。但在某些情况下,它可能在不到一分钟的时间内达到 100,而没有任何加速时间,这会在我的所有请求都失败时导致应用程序状态。所有这 100 个连接都处于 sleeping 状态并且 awaiting command.

好的部分是我找到了一个解决方法来帮助我缓解问题 - 从客户端清除连接池。我正在使用 SqlCoonection.ClearAllPools(),它会立即关闭所有连接,然后 sp_who 会显示我的常规 10-20 连接。

不好的地方,我还不知道根本原因。

澄清一下,应用程序负载约为 200-300 个并发用户,每分钟生成 1000 个请求

@DavidBrowne 提出了用简单模式跟踪泄漏连接的好建议,我能够在配置 Owin 引擎时找到泄漏连接

private void ConfigureOAuthTokenGeneration(IAppBuilder app)
{
    // here in create method I'm creating also a connection leak tracker
    app.CreatePerOwinContext(() => MyCoolDb.Create());
    ...
}

基本上对于每个请求,Owin 都会创建一个连接并且不会放弃它,当 WebAPI 负载增加时我遇到了麻烦。

这可能是真正的原因,我 Owin 足够聪明,可以在需要时懒惰地创建连接(使用提供的功能)并在使用时放手?

极不可能 这不是由您的应用程序代码泄漏连接引起的。

这是一个帮助程序库,您可以使用它来跟踪连接何时泄漏,并报告最初打开连接的调用站点。

http://ssbwcf.codeplex.com/SourceControl/latest#SsbTransportChannel/SqlConnectionLifetimeTracker.cs