2

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

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


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

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

你们有什么想法、建议、建议或陷阱需要我们注意吗?

4

1 回答 1

4

您必须消除连接泄漏。如果池耗尽的原因是泄漏,将其增加到 300 只会延迟不可避免的情况。如果您在 10000 次调用中泄漏一个连接(即“非常罕见”)并且您有 110 个并发请求,例如 5 秒一次调用,那么您以每 8 分钟一个连接的速度泄漏,这将耗尽池13 小时。但是,由于可用池大小将缩小,超时将开始显示得更早。

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

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

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

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

于 2009-07-31T01:56:00.043 回答