【问题标题】:Getting a new connection from the connection pool times out in ASP.Net application. I need suggestions for mitigation在 ASP.Net 应用程序中从连接池获取新连接超时。我需要缓解建议
【发布时间】:2009-07-31 00:22:48
【问题描述】:

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

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


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

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

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

【问题讨论】:

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


    【解决方案1】:

    您必须消除连接泄漏。如果池耗尽的原因是泄漏,将其增加到 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 更改数据库。

    【讨论】:

    • 真正的问题是一个模糊的连接泄漏。感谢您提供详细的 cmets。
    猜你喜欢
    • 2012-04-19
    • 2015-03-27
    • 2014-01-09
    • 2016-06-05
    • 2014-01-28
    • 1970-01-01
    • 1970-01-01
    • 2011-02-08
    • 2012-06-12
    相关资源
    最近更新 更多