连接池是否有益于多线程Java程序

时间:2014-12-05 15:03:49

标签: java multithreading jdbc pool

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

使用像C3P0这样的连接池会有什么好处吗?或者它仅适用于Web应用程序(可扩展到许多用户)?

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

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

感谢任何指导!

2 个答案:

答案 0 :(得分:2)

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

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

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

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

我建议您尝试使用和不使用连接池进行“拔出”测试。运行您的应用程序并为其提供一些操作,拔掉网络电缆,而不是重新插入网络电缆并查看应用程序恢复所需的时间。在池中,只要池能够创建与数据库的新连接,您就应该再次看到应用程序正常运行。

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

答案 1 :(得分:1)

不考虑运行应用程序的位置以及是否将数据库暴露给互联网的问题,我认为添加连接池不会解决您的问题,但它可以改善您的应用程序。

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

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

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

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