我正在开发一个使用EF 6.x连接Azure SQL数据库的ASP.NET MVC应用程序。最近由于负载增加,该应用程序开始进入无法与SQL服务器通信的状态。我可以使用
好的一面是,我找到了一个解决方法来缓解这个问题-从客户端清除连接池。我使用
坏的一面是,我仍然不知道根本原因。
只是为了澄清,该应用程序负载大约为
通过@DavidBrowne的绝妙建议,使用简单模式来跟踪泄漏的连接,在配置
基本上,在每个请求中,
这可能是真正的原因,那么我是否可以相信
exec sp_who
查看到有100个活动连接到我的数据库,任何新连接都无法创建,并显示以下错误消息:
大部分时间,该应用程序的平均活动连接数为10至20个。任何负载都不会改变这个数字...即使负载很高,它也会保持在10-20的水平。但在某些情况下,它可能会在不到一分钟的时间内达到100,而没有任何逐渐增加的时间,这会导致应用程序处于所有请求失败的状态。所有这些100个连接都处于System.Data.Entity.Core.EntityException: 潜在提供程序“System.Data.SqlClient”失败。 ---> System.InvalidOperationException: 超时已过期。 在从池中获取连接之前已经超时。这可能是因为所有池化的连接都在使用并且达到了最大池大小。
睡眠
状态和等待命令
。好的一面是,我找到了一个解决方法来缓解这个问题-从客户端清除连接池。我使用
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
足够聪明,能够在需要时惰性地创建连接(使用提供的函数),并在使用后释放连接呢?
using(var db = new MyDbContext()) { ... }
- Mando