【问题标题】:Connection Pooling - Why test connections on checkin?连接池 - 为什么在签入时测试连接?
【发布时间】:2016-06-16 04:50:29
【问题描述】:

您好,这个问题应该适用于比 c3p0 更多的连接池管理器,但我会以那个为例。

c3p0 为连接池管理提供的一个选项是在连接被检入连接池之前对其进行测试。 这是否意味着在应用程序使用了连接之后?如果是这样,如果它只是被应用程序使用,连接不是总是有效的吗?

除非我的理解是错误的,否则这似乎是检查连接是否有效的无用时间,因为无效的连接会在应用程序尝试使用它时引发异常。

更新: 我要问的真正问题是,刚刚在应用程序中失败的陈旧连接是否仍会被检查回池中以最终一次又一次地失败?如果答案是否定的,那么签入测试将毫无意义,因为“爆炸”连接永远不会被发送回池。多年来,我一直在使用 c3p0 和 testOnCheckIn 和测试查询间隔,但实际上并没有深入了解原因。

【问题讨论】:

  • 无论如何这都是浪费时间,因为唯一感兴趣的问题是当您out 时连接是否有效。 是测试它的时候了。唯一可能的好处是不要将陈旧的连接池化,这可能会在客户端节省空间,但它不会使服务器受益,如果它在客户端没有测试为有效,它显然已经关闭了它的末端。
  • @EJP 那么你同意我的假设吗?这确实是浪费时间。
  • 我写的东西有什么不清楚的地方吗?
  • @EJP 只需再次确认,因为 testOnCheckout 是支持 c3P0 的人推荐的方法。出于性能原因,文档警告不要使用 testOnCheckOut,但我最终将不可避免地这样做,因为对每个事务的简单查询是我当前负载可以承受的。谢谢。

标签: java hibernate connection-pooling c3p0


【解决方案1】:

在结帐时测试连接是否是一个性能问题,很大程度上取决于测试的效率,以及结帐时连接的工作量。正如您所说,配置连接测试的最安全、最简单的方法是在结帐时进行测试。但这也意味着客户端必须经历测试的延迟。

如果您希望异步测试连接,即客户端代码路径之外,那么您希望在签入时测试连接,并在签入连接时定期测试。基本上,策略是为了确保池中空闲的Connections不太可能无效,这样您就可以安全地检查它们而无需测试。 (“安全”当然是程度问题。即使在结帐时测试,连接也可能在测试和第一次客户端使用之间失效。)

假设连接在签入时有效不是一个好主意,因为客户端刚刚使用它。首先,客户端遇到异常这一事实并不一定会向池发出连接无效的信号。例如,对Connection.commit() 的调用可能会因为事务中的行的并发修改而失败,即使连接完全有效。从根本上说,签出连接时遇到的异常是客户的业务,而不是池的业务。 c3p0(我认为不寻常)确实注意到客户端遇到的异常,并触发静默连接测试,以便池可以推断连接有效性。但是客户端可能会遇到来自有效连接的异常的原因有很多。

其次,池不能依赖于客户端最后一次使用连接后的及时签入。这是一个坏主意,但客户端通常将连接打开的时间比他们实际的数据库工作时间长得多。 las 客户端使用和签入之间的任何时间窗口显然都是连接可能出错的窗口。

因此,如果您想要异步连接测试 - 即(对于足够大的池)对客户端延迟没有贡献的连接测试 - 您需要在签入时进行测试,然后在连接被池化和空闲时进行频繁测试.

所有这一切都表明,实际上,异步连接测试的需求已经减少,因为 JDBC 驱动程序现在通过Connection.isValid() 提供快速、可靠的测试。曾几何时,为了定义独立于 DBMS 的可靠连接测试,c3p0 不得不默认对数据库元数据进行通常非常缓慢的查询。此测试的延迟可能会对客户端性能造成真正的影响。使用Connection.isValid()(或高效的preferredTestQuery),测试通常足够快,以至于结账时测试的简单性和稳健性超过了对小客户端延迟的影响。 c3p0 文档用于建议出于性能原因使用异步连接测试。 current documentation 建议首先在结帐时进行同步测试,仅当测试延迟影响性能时才退回到异步测试作为潜在的优化。在大多数情况下,实际上,您现在通常只使用testConnectionsOnCheckout

【讨论】:

  • c3p0(我认为不寻常)确实注意到客户端遇到的异常,并触发静默连接测试,以便池可以推断连接有效性”我没听说过关于这个功能 - 文档中是否有提及,或者您在来源中看到过这个?
  • 太酷了 :) 最好在测试文档附近的文档中提及它。此检查是在异常发生时发生还是在连接返回池后是异步的?有什么影响(如果连接真的断开了)?
  • 谢谢!如果连接被破坏,它被“排除”,这意味着池在用户关闭()时悄悄地破坏它,而不是重新检入它。它没有记录,因为它应该对用户透明 - 只是一种变得更好的方法robutness,而不是“功能”——而且它是不可配置的。如果我能想到一些不尴尬的方法,也许我会在下次修改文档时在某个地方提到它。
  • 知道了,谢谢。同样关于异步检查:“所有这一切都表明,实际上,异步连接测试的需求已经减少,因为 JDBC 驱动程序现在提供了快速”。我认为它们仍然是需要的,例如对于应用程序和数据库之间存在可能中断连接的防火墙的情况。同样在 MySQL 的情况下,如果长时间没有活动,它会断开连接。所以异步检查对我来说仍然很重要。
【解决方案2】:

这是否意味着在应用程序使用了连接之后?

是的

如果是这样,如果它只是被应用程序使用,连接不是总是有效的吗?

如果您的应用使用了连接,但它似乎已损坏,因此引发了异常,该怎么办?在这种情况下,如果您只是将其放回池中,它将再次返回,并且另一个请求将失败。一段时间后,更多的连接可能会中断,失败请求的比例会增加。

有些人倾向于在签入后进行测试的原因是他们害怕签出测试对性能的影响。您的请求必须等到进行涉及网络流量的 SQL 查询。这可能或不可能对您的应用程序造成真正的危害。

我个人没有做过任何性能测试,也不知道这个问题有多严重,但这也取决于您对应用的预期延迟水平。您还可以依赖@Steve Waldman 指出的连接的异步测试 - 这样您就可以在请求处理线程之外测试您的连接。

【讨论】:

  • 谢谢。我想这是有道理的,即使在陈旧的连接刚刚导致崩溃之后,池也无法知道并重新签入。
猜你喜欢
  • 2017-12-02
  • 1970-01-01
  • 2016-04-26
  • 1970-01-01
  • 1970-01-01
  • 2021-01-28
  • 2017-08-02
  • 2019-11-28
  • 1970-01-01
相关资源
最近更新 更多