[英]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 池。
对于 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 的数据库连接池实用程序,支持基于时间的过期、语句缓存、连接验证和使用池管理器的简单配置。”
我们遇到了需要引入连接池的情况,摆在我们面前的有 4 个选项。
我们根据我们的标准进行了一些测试和比较,并决定选择 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.