【问题标题】:Would a connection Pool benefit a multithreaded Java program连接池是否会使多线程 Java 程序受益
【发布时间】:2014-12-05 15:03:49
【问题描述】:

我有一个 java 进程,它启动了大约 60 个线程,每个线程都访问一个 MySql 数据库。

我会从使用像 C3P0 这样的连接池中受益吗?还是仅适用于 Web 应用程序(可扩展到大量用户)?

今天我们有长期存在的 JDBC 连接(每个线程一个),而我的计划是在每次 SQL 查询/插入之前从连接池中获取一个连接。

我想知道这是否会使我们的应用程序更稳定?另外,如果我将其配置为匹配数据库中的最大连接数,线程是否必须等到有空闲连接?文档不是很清楚(至少对我来说不是)。

感谢任何指导!

【问题讨论】:

  • 我不太了解这个应用程序的架构。你能拼出来吗?我从您的描述中得到的是,这是一个带有数据库后端的服务器,您可以使用某些客户端通过 Internet 联系它。如果是这样的话,这和“Web 应用程序”之间的唯一区别是它在哪个端口上运行,不是吗?
  • 问题不是关于架构,而是关于连接池。 (粗鲁的讽刺评论已删除)。与长时间运行的 JDBC 连接相比,Java 是否会从使用连接池中受益的问题(如问题所述,每个线程一个)。 Web 应用程序以完全不同的方式(通常)扩展,您可以拥有 1000 或更多用户。在这里我知道我只有一个进程,但有很多线程。我还能从使用连接池中受益吗?
  • 如果在池中设置最大连接数,池将不再创建。如果给定时间点的所有连接都被其他线程占用,则下一次检索一个连接的调用将阻塞。
  • 终于有人读到了这个问题。谢谢!

标签: java multithreading jdbc pool


【解决方案1】:

您可能可以从连接池中受益。 “通信链接故障”以及长期存在的 JDBC 连接让我怀疑连接在一段时间未使用(空闲)后断开。

HikariCP 这样的数据库连接池可以为您做两件事,可以提供帮助:

  • 在分发之前检查连接是否有效。如果它无效,则丢弃它并分发另一个或一个有效的新连接。这一切都由池完成,您的应用程序不必处理这些。
  • 通过关闭空闲连接(“idleTimeout”)和循环长期连接(“maxLifetime”)来保持连接健康。当坏的网络组件(防火墙)断开任何打开时间超过 30 分钟的连接时,后者特别有用。(*)

如果使用池中的所有连接,则线程可能必须等待(“connectionTimeout”)。但是,如果您的池具有适当的最大大小(“maximumPoolSize”),这将很少是很长的时间。它确实要求您的应用程序尽量减少它使用连接的时间:在获取连接和关闭它(将连接返回到池)之间,您的应用程序应该主要/只执行数据库操作。一个副作用是您将需要更少的连接:在您现在使用 60 的地方,您可能会发现池中只需要 6 个。需要进行一些性能测试以确定适合您的应用程序的“maximumPoolSize”。

我建议您尝试使用和不使用连接池的“拔出”测试。运行你的应用程序并让它做点什么,拔掉网络电缆,然后重新插入网络电缆,看看你的应用程序需要多长时间才能恢复。在池的情况下,一旦池能够创建与数据库的新连接,您应该会看到您的应用程序再次正常运行。

(*) 循环连接还有另一个原因:一些查询可能会在数据库服务器端产生临时数据,并且只要连接处于活动状态,数据库服务器就会一直保持这种状态。这可能导致数据库服务器的内存使用量不断增加。我没有看到这种情况发生,但我知道其他人有。在这种情况下,“maxLifetime”选项非常有用。

【讨论】:

    【解决方案2】:

    撇开您的应用程序在哪里运行以及您的数据库是否暴露在互联网上的问题不谈,我认为添加连接池不会解决您的问题,但它可以改善您的应用程序。

    我猜您的虚假错误是在您使用数据库连接时发生的。我不认识您的特定错误,但这听起来像是某种连接失败,如果您与数据库之间的链接不可靠或速度较慢,则可能会发生这种情况。池在这里没有帮助,因为它是一个连接池。一旦你获得连接,你不知道它是否会因为同样的原因而失败。

    但是,如果您确实使用了池,那么您不必长时间保持连接打开。使用池,您需要一个连接,如果没有可用的连接,将创建一个。返回连接后,如果有一段时间没有使用,它可能会(断开连接)并丢弃。除非您的应用程序始终使用每个连接,否则这对您的应用程序和服务器都有好处。

    即使在这里,您也必须做一些额外的事情来处理失败。假设您从池中建立了一个连接,但随后失败了。您可以关闭它,然后向池请求新连接(池中应该有一些 API 可以摆脱该连接。)新连接可能处于更好的状态。

    最后,考虑也许不要在 Internet 上使用 JDBC。正如其他人可能会指出的那样,这会使自己面临不必要的风险。也许使用某种网络服务通过安全的 https 和更受限制的接口读取和写入数据。

    【讨论】:

    • 感谢您阅读并回答我的问题,而不是纠结于架构问题!我们的应用程序仅供内部使用,我们使用 VPN 和非标准端口,有防火墙等 yada yada 没有什么对这个问题特别感兴趣。什么都没有暴露,所以不要担心。如果我每天有 52 小时,我可能会为这种特殊情况编写一个服务,但我还有很多其他应用程序要编写,而且这个应用程序并不重要。我更多的是在寻找“最佳实践”。我想我现在明白如何使用它了。再次感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-23
    • 2016-07-07
    • 2015-04-03
    • 2012-06-16
    • 2019-07-07
    • 1970-01-01
    • 2016-05-24
    相关资源
    最近更新 更多