3

我试图找出我们在一个高流量站点中使用 Tomcat 6.0.37 和 MySQL 5.5 的问题。测试负载是 200 个与 Tomcat 的并发连接——所有连接都指向同一个 URL,并且都访问数据库。

为了进行连接池,我们使用嵌入式 tomcat-dbcp 包。这是我们使用的资源配置:

    <Resource name="jdbc/appDataSource" auth="Container"
            type="javax.sql.DataSource"
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost/myapp?autoReconnect=true&amp;characterEncoding=UTF-8"
            username="root"
            password="*****"

            testOnBorrow="true"
            maxWait="5000"
            maxIdle="1"
            maxActive="30"
            validationQuery="SELECT 1"
            validationInterval="30000"
            timeBetweenEvictionRunsMillis="30000"

            logAbandoned="true"
            removeAbandoned="true"
            removeAbandonedTimeout="60"
    />

当我在该站点上运行一些测试流量时,我发现连接池大量丢失了连接。大约一分钟后,我对 MySQL 进行了超过 10000 次连接尝试,并且池中的连接从未超过 20 个 - 所有连接几乎都立即关闭。

我尝试通过将其添加到 lib 文件夹并包含属性来切换到 Apache Commons

            factory="org.apache.commons.dbcp.BasicDataSourceFactory"

在我的配置中,但它给了我完全相同的结果。

我尝试切换到 C3P0 和 BoneCP,这实际上工作得很好,我看到最多 30 个连接被保持 - 在 MySQL 上没有新的或丢弃的连接

我也尝试过使用 Apache Tomcat 7 的连接池(只是为了它),它在以下配置中也能很好地工作:

    <Resource name="jdbc/appDataSource" auth="Container"
            type="javax.sql.DataSource"
            factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost/myapp?autoReconnect=true&amp;characterEncoding=UTF-8"
            username="root"
            password="******"

            maxIdle="1"
            maxActive="30"
            validationQuery="SELECT 1"
            validationInterval="30000"
            timeBetweenEvictionRunsMillis="30000"

            logAbandoned="true"
            removeAbandoned="true"
            removeAbandonedTimeout="60"
    />

我想知道 Apache Commons DBCP 是否真的有问题,即使在最简单的情况下也无法正常工作?这一切有解释吗?

4

2 回答 2

0

DBCP 被认为是过时的,而不是用于负载重的系统(多线程)的生产级,建议使用 C3P0 而不是 DBCP。

C3P0 是一个易于使用的库,用于通过使用 jdbc3 规范定义的功能和 jdbc2 的可选扩展来增强传统 JDBC 驱动程序“企业就绪”。

Tomcat 7 似乎带有一个新的连接池作为新特性;它是 commons-dbcp 连接池的替代品。虽然 commons-dbcp 连接池适用于小型或低流量应用程序,但众所周知它在高并发环境中存在问题(想想多核/多 CPU)。

有关 DBCP 与 C3P0 的更多详细信息,请参阅 JDBC 的连接池选项:DBCP与 C3P0。

于 2015-09-10T09:23:03.767 回答
0

您的问题的根源是低 maxIdle 设置。将 maxIdle 设置为 1 意味着在给定时间池中不能有超过 1 个连接处于空闲状态。在高并发负载下,连接的返回速度有时会比借用速度快,从而导致池中的空闲连接瞬间堆积。将 maxIdle 设置为 1,除了第一个空闲连接之外的所有连接都将在返回时关闭。将 maxIdle 保留为默认值(1.x 为 8)或将其设置为等于 maxActive 应该可以提高您的性能。

请参阅https://commons.apache.org/proper/commons-dbcp/api-1.4/org/apache/commons/dbcp/BasicDataSource.html#maxIdle

于 2016-05-15T15:21:38.043 回答