323

可用于 Java/JDBC 的最佳连接池库是什么?

我正在考虑 2 个主要候选人(免费/开源):

我在博客和其他论坛上阅读了很多关于它们的信息,但无法做出决定。

这两个有什么相关的替代品吗?

4

16 回答 16

183

DBCP 已过时,不是生产级。一段时间前,我们对两者进行了内部分析,创建了一个测试夹具,该夹具针对这两者生成负载和并发性,以评估它们在现实生活条件下的适用性。

DBCP 不断地在我们的测试应用程序中生成异常,并且努力达到 C3P0 完全能够在没有任何异常的情况下处理的性能水平。

C3P0 还可以在恢复时稳健地处理 DB 断开连接和透明重新连接,而如果从其下方取出链接,则 DBCP 永远不会恢复连接。更糟糕的是,DBCP 将连接对象返回给底层传输已中断的应用程序。

从那时起,我们在 4 个主要的重载消费类 Web 应用程序中使用了 C3P0,并且从未回头。

更新:事实证明,经过多年的搁置,Apache Commons 的人们已经让DBCP 摆脱了休眠状态,现在它再次成为一个积极开发的项目。因此,我的原始帖子可能已过时。

话虽如此,我还没有体验过这个新升级的库的性能,也没有听说它在任何最近的应用程序框架中都是事实上的。

于 2009-02-06T16:02:23.910 回答
180

我邀请您试用BoneCP——它是免费的、开源的,并且比可用的替代品更快(参见基准部分)。

免责声明:我是作者,所以你可以说我有偏见:-)

更新:截至 2010 年 3 月,仍比新重写的 Apache DBCP(“tomcat jdbc”)池快约 35%。请参阅基准部分中的动态基准链接。

更新 #2:(2013 年 12 月)在 4 年的顶峰之后,现在有一个更快的竞争对手:https ://github.com/brettwooldridge/HikariCP

更新 #3:(2014 年 9 月)请考虑此时已弃用BoneCP ,建议切换到HikariCP

更新 #4:(2015 年 4 月)——我不再拥有域名 jolbox.com

于 2009-11-02T18:42:18.910 回答
16

当连接超时时,我遇到了 DBCP 问题,所以我试用了 c3p0。我打算将其发布到生产环境中,但随后开始了性能测试。我发现 c3p0 的表现非常糟糕。我根本无法将其配置为表现良好。我发现它的速度是 DBCP 的两倍。

然后我尝试了Tomcat 连接池

这比 c3p0 快两倍,并解决了我在使用 DBCP 时遇到的其他问题。我花了很多时间调查和测试这 3 个池。如果您要部署到 Tomcat,我的建议是使用新的 Tomcat JDBC 池。

于 2010-12-14T22:44:53.117 回答
14

对于 DBCP 的自动重新连接问题,是否尝试过使用以下 2 个配置参数?

validationQuery="Some Query"

testOnBorrow=true
于 2009-04-26T03:03:52.863 回答
14

另一种选择是HikariCP

这是比较基准

于 2016-04-01T04:41:51.730 回答
12

几年来一直在生产中使用 DBCP。它很稳定,可以在数据库服务器重新启动后继续存在。只需正确配置即可。它只需要指定几个参数,所以不要偷懒。这是我们系统生产代码的一个片段,其中列出了我们明确设置以使其工作的参数:

DriverAdapterCPDS driverAdapterCPDS = new DriverAdapterCPDS();
driverAdapterCPDS.setUrl(dataSourceProperties.getProperty("url"));
driverAdapterCPDS.setUser(dataSourceProperties.getProperty("username"));
driverAdapterCPDS.setPassword(dataSourceProperties.getProperty("password"));
driverAdapterCPDS.setDriver(dataSourceProperties.getProperty("driverClass"));

driverAdapterCPDS.setMaxActive(Integer.valueOf(dataSourceProperties.getProperty("maxActive")));
driverAdapterCPDS.setMaxIdle(Integer.valueOf(dataSourceProperties.getProperty("maxIdle")));
driverAdapterCPDS.setPoolPreparedStatements(Boolean.valueOf(dataSourceProperties.getProperty("poolPreparedStatements")));

SharedPoolDataSource poolDataSource = new SharedPoolDataSource();
poolDataSource.setConnectionPoolDataSource(driverAdapterCPDS);
poolDataSource.setMaxWait(Integer.valueOf(dataSourceProperties.getProperty("maxWait")));
poolDataSource.setDefaultTransactionIsolation(Integer.valueOf(dataSourceProperties.getProperty("defaultTransactionIsolation")));
poolDataSource.setDefaultReadOnly(Boolean.valueOf(dataSourceProperties.getProperty("defaultReadOnly")));
poolDataSource.setTestOnBorrow(Boolean.valueOf(dataSourceProperties.getProperty("testOnBorrow")));
poolDataSource.setValidationQuery("SELECT 0");
于 2011-12-18T17:05:24.797 回答
8

这里有一些文章表明 DBCP 的性能明显高于 C3P0 或 Proxool。此外,根据我自己的经验,c3p0 确实有一些不错的功能,例如准备好的语句池,并且比 DBCP 更易于配置,但在我使用过的任何环境中,DBCP 显然都更快。

dbcp 和 c3p0 的区别?绝对没有!(Sakai 开发者博客) http://blogs.nyu.edu/blogs/nrm216/sakaidelic/2007/12/difference_between_dbcp_and_c3.html

另请参阅博客文章评论中对 JavaTech 文章“Connection Pool Showdown”的赞。

于 2010-01-07T03:11:39.413 回答
7

本文提到了另一种替代方案 Proxool 。

您可能会发现为什么 Hibernate 将 c3p0 捆绑为其默认连接池实现?

于 2009-02-06T15:18:26.680 回答
7

不幸的是,它们都已经过时了。DBCP 最近更新了一点,另外两个是 2-3 岁,有很多突出的 bug。

于 2009-09-01T17:06:40.250 回答
7

如果配置正确,则 Dbcp 可用于生产。

例如,它用于一个每天有 350000 名访问者和 200 个连接池的商业网站。

如果您正确配置它,它可以很好地处理超时。

版本 2 正在进行中,它的背景使其可靠,因为已经解决了许多生产问题。

我们将它用于我们的批处理服务器解决方案,它已经运行了数百个批处理,这些批处理在数据库中的数百万行上工作。

由tomcat jdbc pool 运行的性能测试表明它比cp30 具有更好的性能。

于 2011-05-11T21:04:19.067 回答
4

刚刚用 DBCP 浪费了一天半的时间。即使我使用的是最新的 DBCP 版本,我也遇到了与j pimmel完全相同的问题。我根本不推荐 DBCP,尤其是当 DB 消失时它会从池中抛出连接,当 DB 回来时它无法重新连接,并且它无法动态地将连接对象添加回池中(它永远挂在一个 post JDBCconnect I/O 套接字读取)

我现在正在切换到 C3P0。我在以前的项目中使用过它,它的工作和表现就像一个魅力。

于 2010-08-14T02:01:50.167 回答
4

当我们使用多线程项目时,c3p0 很好。在我们的项目中,我们使用 DBCP 同时使用多个线程执行,然后如果我们使用更多线程执行,我们就会出现连接超时。所以我们选择了 c3p0 配置。

于 2011-07-15T11:49:01.017 回答
3

一个易于使用的好选择是DBPool

“一个基于 Java 的数据库连接池实用程序,支持基于时间的到期、语句缓存、连接验证以及使用池管理器的简单配置。”

http://www.snaq.net/java/DBPool/

于 2010-08-20T22:38:08.470 回答
3

我们遇到了需要引入连接池的情况,我们面前有 4 个选项。

  • DBCP2
  • C3P0
  • 雄猫 JDBC
  • 光CP

我们根据我们的标准进行了一些测试和比较,并决定选择 HikariCP。阅读这篇文章,了解我们选择 HikariCP 的原因。

于 2018-02-13T05:21:38.023 回答
2

我的建议是

光 > 德鲁伊 > UCP > c3p0 > DBCP

它基于我测试过的内容 - 20190202,在我的本地测试环境中(docker/pool minSize=1,maxSize=8 中的 4GB mac/mysql),hikari 可以服务 1024 个线程 x 1024 次获得连接,每个线程的平均时间完成是 1 或 200 万秒,而 c3p0 只能服务 256 个线程 x 1024 次,每个线程的平均时间已经是 2100 万秒。(512 个线程失败)。

于 2019-02-02T04:38:33.327 回答
1

要以最佳方式实施 C3P0,请检查此答案

C3P0

对于企业应用,C3P0 是最好的方法。C3P0 是一个易于使用的库,用于使用 JNDI 可绑定数据源(包括实现连接和语句池的数据源)增强传统(基于 DriverManager)的 JDBC 驱动程序,如 jdbc3 规范和 jdbc2 std 扩展所述。C3P0 还可以在恢复时稳健地处理 DB 断开连接和透明重新连接,而如果从其下方取出链接,则 DBCP 永远不会恢复连接。

所以这就是 c3p0 和其他连接池也有准备好的语句缓存的原因——它允许应用程序代码避免处理所有这些。语句通常保存在一些有限的 LRU 池中,因此常见的语句重用 PreparedStatement 实例。

更糟糕的是,DBCP 将连接对象返回给底层传输已中断的应用程序。c3p0 的一个常见用例是替换 Apache Tomcat 中包含的标准 DBCP 连接池。程序员经常会遇到连接在 DBCP 连接池中没有正确回收的情况,而 c3p0 在这种情况下是一个有价值的替代品。

在当前更新中,C3P0 具有一些出色的功能。这些在下面给出:

ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setMinPoolSize();
dataSource.setMaxPoolSize();
dataSource.setMaxIdleTime();
dataSource.setMaxStatements();
dataSource.setMaxStatementsPerConnection();
dataSource.setMaxIdleTimeExcessConnections();

在这里,max 和 min poolsize定义了连接范围,这意味着该应用程序将采用的最小和最大连接。MaxIdleTime()定义何时释放空闲连接。

数据库CP

这种方法也很好,但有一些缺点,如连接超时和连接释放。当我们使用多线程项目时,C3P0 很好。在我们的项目中,我们使用 DBCP 同时使用多个线程执行,然后如果我们使用更多线程执行,我们就会出现连接超时。所以我们选择了 c3p0 配置。我根本不会推荐 DBCP,尤其是当 DB 消失时它会从池中抛出连接,当 DB 回来时它无法重新连接,并且它无法动态地将连接对象添加回池中(它永远挂在一个 post JDBCconnect I/O 套接字读取)

谢谢 :)

于 2018-08-14T09:02:23.620 回答