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

我正在考虑2个主要候选对象(免费/开放源代码): DBCP-http://commons.apache.org/dbcp/

C3P0-http://sourceforge.net/projects/c3p0


我已经在博客和其他论坛上阅读了很多有关它们的内容,但仍未做出决定。

#1 楼

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

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

C3P0还可以稳健地处理数据库断开连接和恢复时的透明重新连接,而如果从其下方拔出链接,则DBCP永远不会恢复连接。更糟糕的是,DBCP正在将Connection对象返回到基础传输中断的应用程序。

从那时起,我们就在4个主要的重型消费类Web应用程序中使用了C3P0,并且再也没有回过头。在架子上,Apache Commons员工使DBCP脱离了休眠状态,现在它又是一个积极开发的项目。因此,我的原始帖子可能已过时。

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

评论


谢谢!建议的Proxool替代品怎么样? Hibernate的当前版本随附c3p0和Proxool。

–德玛
09年2月6日在16:49

我们还没有尝试过Proxool,但我一定会立即检查出来的:)

– j pimmel
09年2月6日在17:48

c3p0有一些缺点。有时无法处理连接峰值。

–詹宁
2010-10-26 15:22

自您首次发布此答案的4年以来,情况发生了很大变化,是否可以添加共享当前情况的更新?

–拉贾特·古普塔(Rajat Gupta)
13年8月18日在18:21

我强烈推荐HikariCP,但后来我帮忙编写了它。

–brettw
13年11月16日在8:16

#2 楼

我邀请您试用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

评论


真的很喜欢使用BoneCP作为Tomcat数据源进行故障排除。我遇到的主要问题是,它需要tomcat的lib目录中的BoneCP类,以及log4j和google类。这样做使连接池工作-(在WAR中没有用)-但是它与Tomcat的log4j设置冲突,并完全阻止了应用程序的任何日志输出,这是一个大问题。

– j pimmel
2010年6月18日15:40

这听起来更像是log4j问题。在forum.jolbox.com上给我留言,我会尽快帮助您跟踪。

– wwadge
2010-6-20 at 16:59

1up,BoneCP非常出色。从C3P0切换。它甚至允许我删除对log4jdbc-remix的依赖,因为它允许开箱即用地记录语句!

–子
2011年2月2日,19:46

+1用于更新您未写的内容的速度更快!

– CorayThan
2014年4月23日下午16:51

@AndrewScottEvans可能最好恢复到v0.7.1

– wwadge
2014年6月10日上午10:36

#3 楼

连接超时时,我在使用DBCP时遇到麻烦,因此我试用了c3p0。我打算将其发布到生产环境,然后开始性能测试。我发现c3p0表现出色。我无法将其配置为完全正常。我发现它的速度是DBCP的两倍。

然后我尝试了Tomcat连接缓冲。我花了很多时间研究和测试这三个游泳池。如果要部署到Tomcat,我的建议是使用新的Tomcat JDBC池。

#4 楼

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

validationQuery="Some Query"

testOnBorrow=true


评论


关于文档,testOnBorrow的默认值为true,因此,如果定义了validateQuery,则DBCP将在将每个连接传递给应用程序之前对其进行测试。

– dma_k
11-10-17在10:02

#5 楼

另一个选择是HikariCP。

这是比较基准

#6 楼

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

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");


#7 楼

以下是一些文章,它们表明DBCP的性能明显高于C3P0或Proxool。同样,根据我自己的经验,c3p0确实具有一些不错的功能,例如预准备语句池,并且比DBCP更可配置,但是在我使用过的任何环境中,DBCP显然都更快。 ?绝对没有! (Sakai开发人员博客)
http://blogs.nyu.edu/blogs/nrm216/sakaidelic/2007/12/difference_between_dbcp_and_c3.html

另请参见JavaTech文章的类似文章“博客评论中的“连接池对决”。

评论


在单线程环境中,速度可能更快,可能是越野车和不稳定的,甚至在其他任何地方都被破坏了。

–user177800
2010年6月4日在17:31

#8 楼

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

#9 楼

不幸的是,他们都过时了。 DBCP最近进行了一些更新,另外两个已使用2-3年,其中有许多未解决的错误。

评论


的确如此-C3PO的最新版本(0.9版)是2007年5月。Proxool的最新版本(0.9版)是2008年8月。DBCP的最新版本也是2007年4月。至少其稳定的1.2版本。那里实际上有什么维护吗?

–古斯
09年12月10日在21:33

公平地说,这些不是大项目,因此您应该期望C3P0 / DBCP中的更新会越来越少,而且时间也会流逝。

– wwadge
09年12月17日在16:57

#10 楼

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

例如,在每天访问量为350000的商业网站上,并具有200个连接池。

它可以很好地处理超时问题只要您正确配置它。

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

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

评论


UBIK LOAD PACK-我们正在使用DBCP 1.4,并在具有10000条记录的单个批处理中不断发生挂起。我们正在使用Spring Batch + JSR 352,并考虑切换到HikariCP。当您说100批次运行平稳时,您是说它与DBCP 2.x或任何其他版本一起运行吗?另外,您介意共享配置吗?我们的配置是maxActive = 150,minIdle = 15,maxIdle = 75,initialSize = 15,但还没有看到挂起的迹象。我们没有使用任何validationQuery或testOnBorrow / testOnReturn。您是否建议使用它?

– Yogendra
16年5月20日在14:38

#11 楼

用DBCP浪费了一天半的时间。即使我正在使用最新的DBCP版本,也遇到了与j pimmel完全相同的问题。我根本不建议使用DBCP,尤其是当数据库消失时,它会把连接从池中抛出,如果DB回来时它无法重新连接,并且无法将连接对象动态地添加回池中(这种情况会永远挂死) JDBCconnect I / O套接字读取后)

我现在要切换到C3P0。我在以前的项目中已经使用过它,并且它的工作和表现都非常吸引人。

#12 楼

当我们使用多线程项目时,c3p0很好。在我们的项目中,通过使用DBCP同时使用了多个线程执行,如果使用更多的线程执行,则连接超时。因此,我们进行了c3p0配置。

#13 楼

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

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

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

评论


我对DBPool与BoneCP进行了基准测试。 DBPool使getConnection()在其他方面保持同步,并且比BoneCP慢得多(请参阅:jolbox.com/forum/viewtopic.php?f=3&t=175)。

– wwadge
2010-12-29 19:45



#14 楼

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


DBCP2
C3P0
Tomcat JDBC
HikariCP

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

#15 楼

我的建议是

hikari> druid> UCP> c3p0> DBCP

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

#16 楼

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

C3P0:

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

所以这就是为什么c3p0和其他连接池还准备了语句高速缓存的原因-它允许应用程序代码避免处理所有这些问题。语句通常保存在一些有限的LRU池中,因此常见语句会重用PreparedStatement实例。更糟糕的是,DBCP仍将Connection对象返回到基础传输中断的应用程序。
A c3p0的常见用例是替换Apache Tomcat附带的标准DBCP连接池。通常,程序员会遇到这样的情况,即在DBCP连接池中连接没有正确回收,并且在这种情况下c3p0是有价值的替代品。下面给出了这些:

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


此处,最大和最小池大小定义了连接范围,这意味着此应用程序将采用最小和最大连接方式。 MaxIdleTime()定义何时释放空闲连接。当我们使用多线程项目时很好。在我们的项目中,通过使用DBCP同时使用了多个线程执行,然后,如果使用更多的线程执行,则连接超时。因此,我们进行了c3p0配置。
我根本不建议使用DBCP,尤其是当数据库消失时,它会把连接从池中抛出,如果DB回来时它无法重新连接,并且无法将连接对象动态地添加回池中(它永远挂在了JDBCconnect I / O套接字后阅读)

谢谢:)