繁体   English   中英

JDBC 的连接池选项:DBCP 与 C3P0 [关闭]

[英]Connection pooling options with JDBC: DBCP vs C3P0 [closed]

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

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

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

这两个是否有任何相关的替代方案?

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

DBCP 始终在我们的测试应用程序中生成异常,并努力达到 C3P0 能够毫无异常地处理的性能水平。

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

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

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

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

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

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

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

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

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

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

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

然后我尝试了Tomcat 连接池

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

另一种选择是HikariCP

这是比较基准

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

validationQuery="Some Query"

testOnBorrow=true

几年来一直在生产中使用 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");

这里有一些文章表明 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 文章“连接池摊牌”。

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

本文中提到了另一种选择 Proxool。

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

如果配置正确,Dbcp 就可以投入生产。

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

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

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

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

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

刚刚完成了在 DBCP 上浪费了一天半的时间。 即使我使用的是最新的 DBCP 版本,我也遇到了与j pimmel完全相同的问题。 我根本不推荐 DBCP,特别是它在数据库消失时将连接从池中抛出的诀窍,在数据库返回时无法重新连接以及无法将连接对象动态添加回池中(它永远挂起后 JDBCconnect I/O 套接字读取)

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

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

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

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

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

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

  • DBCP2
  • C3P0
  • 汤姆猫JDBC
  • 光CP

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

我的建议是

hikari > 德鲁伊 > UCP > c3p0 > DBCP

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

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

C3P0

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

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

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

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

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

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

DBCP

这种方法也很好,但有一些缺点,如连接超时和连接释放。 当我们使用多线程项目时,C3P0 很好。 在我们的项目中,我们通过使用 DBCP 同时使用多个线程执行,然后如果我们使用更多线程执行,我们就会出现连接超时。 所以我们使用 c3p0 配置。 我根本不推荐 DBCP,特别是它在数据库消失时将连接从池中抛出的诀窍,在数据库返回时无法重新连接以及无法将连接对象动态添加回池中(它永远挂起后 JDBCconnect I/O 套接字读取)

谢谢:)

暂无
暂无

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

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