可用于 Java/JDBC 的最佳连接池库是什么?
我正在考虑 2 个主要候选人(免费/开源):
- Apache DBCP - http://commons.apache.org/dbcp/
- C3P0 - http://sourceforge.net/projects/c3p0
我在博客和其他论坛上阅读了很多关于它们的信息,但无法做出决定。
这两个有什么相关的替代品吗?
可用于 Java/JDBC 的最佳连接池库是什么?
我正在考虑 2 个主要候选人(免费/开源):
我在博客和其他论坛上阅读了很多关于它们的信息,但无法做出决定。
这两个有什么相关的替代品吗?
DBCP 已过时,不是生产级。一段时间前,我们对两者进行了内部分析,创建了一个测试夹具,该夹具针对这两者生成负载和并发性,以评估它们在现实生活条件下的适用性。
DBCP 不断地在我们的测试应用程序中生成异常,并且努力达到 C3P0 完全能够在没有任何异常的情况下处理的性能水平。
C3P0 还可以在恢复时稳健地处理 DB 断开连接和透明重新连接,而如果从其下方取出链接,则 DBCP 永远不会恢复连接。更糟糕的是,DBCP 将连接对象返回给底层传输已中断的应用程序。
从那时起,我们在 4 个主要的重载消费类 Web 应用程序中使用了 C3P0,并且从未回头。
更新:事实证明,经过多年的搁置,Apache Commons 的人们已经让DBCP 摆脱了休眠状态,现在它再次成为一个积极开发的项目。因此,我的原始帖子可能已过时。
话虽如此,我还没有体验过这个新升级的库的性能,也没有听说它在任何最近的应用程序框架中都是事实上的。
我邀请您试用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
当连接超时时,我遇到了 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 文章“Connection Pool Showdown”的赞。
本文提到了另一种替代方案 Proxool 。
您可能会发现为什么 Hibernate 将 c3p0 捆绑为其默认连接池实现?
不幸的是,它们都已经过时了。DBCP 最近更新了一点,另外两个是 2-3 岁,有很多突出的 bug。
如果配置正确,则 Dbcp 可用于生产。
例如,它用于一个每天有 350000 名访问者和 200 个连接池的商业网站。
如果您正确配置它,它可以很好地处理超时。
版本 2 正在进行中,它的背景使其可靠,因为已经解决了许多生产问题。
我们将它用于我们的批处理服务器解决方案,它已经运行了数百个批处理,这些批处理在数据库中的数百万行上工作。
由tomcat jdbc pool 运行的性能测试表明它比cp30 具有更好的性能。
刚刚用 DBCP 浪费了一天半的时间。即使我使用的是最新的 DBCP 版本,我也遇到了与j pimmel完全相同的问题。我根本不推荐 DBCP,尤其是当 DB 消失时它会从池中抛出连接,当 DB 回来时它无法重新连接,并且它无法动态地将连接对象添加回池中(它永远挂在一个 post JDBCconnect I/O 套接字读取)
我现在正在切换到 C3P0。我在以前的项目中使用过它,它的工作和表现就像一个魅力。
当我们使用多线程项目时,c3p0 很好。在我们的项目中,我们使用 DBCP 同时使用多个线程执行,然后如果我们使用更多线程执行,我们就会出现连接超时。所以我们选择了 c3p0 配置。
一个易于使用的好选择是DBPool。
“一个基于 Java 的数据库连接池实用程序,支持基于时间的到期、语句缓存、连接验证以及使用池管理器的简单配置。”
我们遇到了需要引入连接池的情况,我们面前有 4 个选项。
我们根据我们的标准进行了一些测试和比较,并决定选择 HikariCP。阅读这篇文章,了解我们选择 HikariCP 的原因。
我的建议是
光 > 德鲁伊 > 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 个线程失败)。
要以最佳方式实施 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 套接字读取)
谢谢 :)