从连接池获取新连接在ASP.Net应用程序中超时。我需要缓解建议

时间:2009-07-31 00:22:49

标签: sql-server ado.net connection-pooling

我们在中等负载下偶尔会在某个数据库上收到以下错误。

“System.InvalidOperationException:Timeout expired。从池中获取连接之前经过的超时时间。这可能是因为所有池连接都在使用中,并且最大池大小是达到了“


我已经梳理了代码,我们正在关闭finally块中的连接,就像我们应该这样,除了在我们已经建立的一些情况下很少被调用。我们将在下一个版本中修复这些代码但是为了解决当前的生产问题,我建议将最大池大小增加到300.我们当前遇到的最大并发用户数大约是110,这显然超过了默认池大小( 100)。

我还建议确保所有与特定SQL Server实例的连接字符串相同,以避免不必要地创建多个连接池。我希望在我们需要在单个SQL Server实例中切换数据库时,我们可以在实际SQL查询之前使用 USE [Database] 语句。

你们有任何想法,指示,建议或陷阱让我们注意吗?

1 个答案:

答案 0 :(得分:4)

您必须消除连接泄漏。如果池耗尽的原因是泄漏,将其增加到300就会延迟不可避免的。如果您在10000个呼叫中泄漏一个连接(即“很少”),并且您有110个并发请求,比如5秒钟的呼叫,那么您每隔8分钟就会以大约一个连接的速率泄漏,从而导致13个小时超时将开始显示得更早,因为可用的池大小将缩小。

如果您有确凿的证据表明不是泄漏是根本原因,而是确实是调用率与池大小,那么您应该增加池大小。无论您决定使用哪种池大小,如果您的请求在整个请求期间需要1:1连接,那么您需要对HTTP接受进行限制/排队,以使其不超过您的池大小。如果没有,你仍然可以遇到使游泳池耗尽的尖峰。

此外,可能考虑使用更具弹性的连接工厂,如果池已耗尽,则会重试并尝试非池连接。当然,这与我之前的观点密切相关,即如果您校准最大HTTP接受计数以匹配池大小,则池不能用尽(除非您泄漏,回到原点)。我不建议这样做,我认为在http.sys区域中排队请求比在应用程序资源分配区域排队要好得多(即限制最大接受的HTTP调用)。

最后但并非最不重要的是,减少每次通话的持续时间。如果您的通话平均需要5秒钟,那么您每秒仅需22次请求即可同时看到110个连接。如果通过消除SQL瓶颈到1秒来减少呼叫持续时间,您将能够每秒服务110个请求以达到相同的资源上限(110个并发请求),即5次流量增加。最大的罪魁祸首通常是表扫描,确保所有查询都使用合理的SQL并拥有最佳的数据访问路径。正如David所说,SQL Profiler是你的朋友。

您还可以使用SqlConnection.ChangeDatabase更改数据库。