【问题标题】:Connection pooling options with JDBC: DBCP vs C3P0 [closed]使用 JDBC 的连接池选项:DBCP 与 C3P0 [关闭]
【发布时间】:2010-10-05 22:56:31
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: java jdbc connection-pooling c3p0 apache-commons-dbcp


    【解决方案1】:

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

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

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

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

    更新:事实证明,经过多年的搁置,Apache Commons 人员已经接受了DBCP out of dormancy,现在它再次成为一个积极开发的项目。因此,我的原始帖子可能已过时。

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

    【讨论】:

    • 谢谢!建议的 Proxool 替代品怎么样?当前版本的 Hibernate 带有 c3p0 和 Proxool。
    • 我们还没有尝试过 Proxool,但我现在一定会去看看 :)
    • c3p0 有一些缺点。它有时无法处理连接高峰。
    • 自从您首次发布此答案 4 年以来,情况发生了很大变化,如果可能的话,您能否添加一个共享当前场景的更新?
    • 我强烈推荐HikariCP,但后来我帮忙写了。
    【解决方案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 设置冲突,并且完全阻止了应用程序的任何日志输出,这是一个破坏者......
    • 这听起来更像是一个 log4j 问题。请在 forum.jolbox.com 上给我留言,我会帮助您尽快找到它。
    • 1up,BoneCP 很棒。从 C3P0 切换。它甚至允许我删除对 log4jdbc-remix 的依赖,因为它允许开箱即用的语句登录!
    • @AndrewScottEvans 最好恢复到 v0.7.1
    • 2016 年了 - HikariCP 仍然是最佳选择吗?
    【解决方案3】:

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

    然后我尝试了Tomcat connection pooling

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

    【讨论】:

      【解决方案4】:

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

      validationQuery="Some Query"
      
      testOnBorrow=true
      

      【讨论】:

      • 对于documentationtestOnBorrow 的默认值为true,因此如果定义了validationQuery,DBCP 将在传递给应用程序之前测试每个连接。
      【解决方案5】:

      另一种选择是HikariCP

      这里是比较benchmark

      【讨论】:

        【解决方案6】:

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

        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 在我使用过的任何环境中都明显更快。

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

          另请参阅博客文章中 cmets 中的 JavaTech 文章“连接池决战”。

          【讨论】:

          • 在单线程环境中速度更快,也许,有问题且不稳定,并且在其他任何地方都被破坏了。
          【解决方案8】:

          this article 中提到了另一个替代方案 Proxool。

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

          【讨论】:

            【解决方案9】:

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

            【讨论】:

            • 这是真的 - C3PO 的最后一个版本(0.9 预发行版)是从 2007 年 5 月开始的。Proxool 的最新版本(0.9 预发行版)是从 2008 年 8 月开始的。 DBCP 也是从 2007 年 4 月开始的,但至少它是一个稳定的 1.2 版本。那里有什么实际维护的东西吗?
            • 公平地说,这些都不是大项目,所以您应该期望 C3P0/DBCP 中的更新越来越少,并且随着时间的推移。
            【解决方案10】:

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

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

            只要您正确配置它,它就能很好地处理超时。

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

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

            tomcat jdbc pool 的性能测试显示它比 cp30 有更好的性能。

            【讨论】:

            • 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。你推荐使用它吗?
            【解决方案11】:

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

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

            【讨论】:

              【解决方案12】:

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

              【讨论】:

                【解决方案13】:

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

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

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

                【讨论】:

                【解决方案14】:

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

                • DBCP2
                • C3P0
                • Tomcat JDBC
                • HikariCP

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

                【讨论】:

                  【解决方案15】:

                  我的建议是

                  hikari > 德鲁伊 > 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 个线程失败)。

                  【讨论】:

                    【解决方案16】:

                    以最好的方式实现 C3P0 然后check this answer

                    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() 定义何时释放空闲连接。

                    DBCP

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

                    谢谢:)

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2010-11-30
                      • 2012-07-06
                      • 2022-08-09
                      • 2011-02-07
                      • 1970-01-01
                      • 1970-01-01
                      • 2013-08-20
                      • 2013-09-04
                      相关资源
                      最近更新 更多