简体   繁体   English

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

[英]Would a connection Pool benefit a multithreaded Java program

I have a java process that starts about 60 threads that each access a MySql database. 我有一个java进程,它启动大约60个线程,每个线程访问一个MySql数据库。

Would I benefit from using a Connection Pool like C3P0? 使用像C3P0这样的连接池会有好处吗? Or is it meant only for Web apps (that scale to lots of users) ? 或者它仅适用于Web应用程序(可扩展到许多用户)?

Today we have long-living JDBC Connections (one per thread), and my plan was to instead get a Connection from the Connection Pool before every SQL query/insert. 今天我们有长期存在的JDBC连接(每个线程一个),我的计划是在每次SQL查询/插入之前从连接池获取连接。

I wonder whether that would make our application more stable? 我想知道这是否会使我们的应用程序更稳定? Also, if I configure it to match the max number of connections in the database, will the thread have to wait until there is a free connection? 另外,如果我将其配置为匹配数据库中的最大连接数,那么线程是否必须等到有空闲连接? The documentation isnt very clear (at least not for me). 文档不是很清楚(至少不适合我)。

Any guidance is appreciated! 任何指导表示赞赏!

You probably can benefit from a connection pool. 您可能可以从连接池中受益。 The "Communications link failure" together with long-lived JDBC connections makes me suspect the connection is broken after some time of not being used (idle). “通信链路故障”与长期存在的JDBC连接一起使我怀疑在一段时间未使用(空闲)后连接中断。

A database connection pool like HikariCP does 2 things for you that can help: HikariCP这样的数据库连接池为您做了两件事可以提供帮助:

  • check a connection is valid before handing it out. 在交付之前检查连接是否有效。 If it is not valid, it is discarded and another one or a new connection that is valid is handed out. 如果它无效,则将其丢弃,并分发另一个有效的新连接。 This is all done by the pool, your application does not have to take care of this. 这一切都是由池完成的,您的应用程序不必处理这个问题。
  • keep connections healthy by closing idle connections ("idleTimeout") and cycling long-lived connections ("maxLifetime"). 通过关闭空闲连接(“idleTimeout”)和循环长期连接(“maxLifetime”)来保持连接的健康。 The latter is especially useful when bad network components (firewalls) drop any connection that is open for longer than, let's say, 30 minutes.(*) 当糟糕的网络组件(防火墙)丢弃任何打开时间超过(例如30分钟)的连接时,后者尤其有用。(*)

If all connections from the pool are used, a thread might have to wait ("connectionTimeout"). 如果使用了池中的所有连接,则线程可能必须等待(“connectionTimeout”)。 But if your pool has a proper maximum size ("maximumPoolSize") this will rarely be a long time. 但是,如果您的池具有适当的最大大小(“maximumPoolSize”),这将很少很长时间。 It does require your application to minimize the time it uses a connection: between getting a connection and closing it (which returns the connection to the pool), your application should mostly/only perform database actions. 它确实需要您的应用程序最小化它使用连接的时间:在获取连接和关闭连接(返回到池的连接)之间,您的应用程序应该主要/仅执行数据库操作。 A side effect will be that you will need far less connections: where you use 60 now, you might find that you only need 6 in the pool. 副作用是您将需要更少的连接:现在使用60,您可能会发现您只需要6个池。 Some performance testing is needed to determine the proper "maximumPoolSize" for your application. 需要进行一些性能测试,以确定适合您应用的“maximumPoolSize”。

I suggest you try an "unplug" test with and without a connection pool. 我建议您尝试使用和不使用连接池进行“拔出”测试。 Run your application and give it something to do, unplug the network cable, than plug the network cable back in and see how long it takes your application to recover. 运行您的应用程序并为其提供一些操作,拔掉网络电缆,而不是重新插入网络电缆并查看应用程序恢复所需的时间。 In the pool-case, you should see your application functioning normally again as soon as the pool is able to create a new connection to the database. 在池中,只要池能够创建与数据库的新连接,您就应该再次看到应用程序正常运行。

(*) There is another reason for cycling connections: some queries may produce temporary data on the database server side and the database server may keep this around for as long as the connection is alive. (*)循环连接还有另一个原因:某些查询可能会在数据库服务器端生成临时数据,并且只要连接处于活动状态,数据库服务器就可以保留这些数据。 This could result in an ever increasing memory usage by the database server. 这可能导致数据库服务器的内存使用量不断增加。 I have not seen this happen, but I know others have. 我没有看到这种情况发生,但我知道其他人有。 A "maxLifetime" option is very useful in such a case. 在这种情况下,“maxLifetime”选项非常有用。

Putting aside the questions of where your application is running and whether you have your database exposed to the internet, I don't think adding a connection pool will fix your problem, but it could improve your application. 暂且不谈运行应用程序的位置以及是否将数据库暴露给互联网,我认为添加连接池不会解决您的问题,但它可以改善您的应用程序。

I'm guessing that your spurious errors are happening when you are using your database connection. 我猜你在使用数据库连接时发生了虚假错误。 I don't recognize your particular error, but it sounds like a connection failure of some sort, which could happen if you had unreliable or slow links between you and the database. 我不承认您的特定错误,但它听起来像是某种类型的连接失败,如果您与数据库之间的链接不可靠或缓慢,则可能会发生这种情况。 The pool wouldn't help here because it is a pool of connections. 游泳池在这里没有帮助,因为它是一个连接池。 Once you obtain the connection, you don't know whether it will then fail or not for the same reasons. 获得连接后,由于同样的原因,您不知道它是否会失败。

However, if you do use a pool, then you don't have to keep the connection open for extended periods. 但是,如果您使用池,则不必长时间保持连接打开。 With a pool, you ask for a connection, and one will be created if none is available. 使用池时,您要求建立连接,如果没有,则会创建一个连接。 After you return the connection, it might be (disconnected) and disposed if it hasn't been used for a while. 返回连接后,如果连接暂时没有使用,它可能会(断开连接)并处理掉。 Unless your application is constant using every connection, then this would be good for both your app and the server. 除非您的应用程序使用每个连接都是常量,否则这对您的应用程序和服务器都有好处。

Even here, you have to do something extra to handle the failure. 即使在这里,你也必须做一些额外的事情来处理失败。 Let's say you have taken a connection from the pool, and it has subsequently failed. 假设您已经从池中获取了连接,并且随后失败了。 You could close it, and ask the pool for a new connection (there should be some API in the pool to get rid of that connection.) A new connection might be in a better state. 您可以关闭它,并向池请求新连接(池中应该有一些API来摆脱该连接。)新连接可能处于更好的状态。

Finally, consider perhaps not using JDBC over the internet. 最后,考虑一下也许不要在互联网上使用JDBC。 As other people are likely to point out, this is exposing yourself to unnecessary risk. 正如其他人可能指出的那样,这会让自己面临不必要的风险。 Perhaps use a webservice of some kind to read and write data over secure https and a more restricted interface. 也许使用某种Web服务来通过安全的https和更受限制的界面读取和写入数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM