【问题标题】:Database connections count greater than that set by DBCP maxTotal数据库连接数大于 DBCP maxTotal 设置的数
【发布时间】:2019-03-25 13:39:33
【问题描述】:

我正在使用 Tomcat(版本 8.0.43)运行一个 java Web 应用程序。

我将 tomcat-dbcp.jar(Tomcat8.0.43 附带)移至 jdk/jre/lib/ext,以便 jre 可以使用它。

我认为我使用的是 Tomcat DBCP(而不是 Apache Commons DBCP),但正如我从 documentation 中了解到的那样,配置参数与 Apache Commons DBCP 相同,详细信息 here。

据此,我在context.xml中为连接池设置了如下Resource元素:

<Resource 
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
auth="Container" 
driverClassName="com.mysql.jdbc.Driver"  
logAbandoned="false" 
maxTotal="100" 
maxIdle="30" 
maxWaitMillis="10000" 
name="jdbc/[dbName]" 
password="${dbPassword}" 
removeAbandonedOnBorrow="true" 
removeAbandonedTimeout="60" 
type="javax.sql.DataSource" 
url="[dbUrl]autoReconnect=true" 
username="${dbUsername}" 
testWhileIdle="true" 
testOnBorrow="true" 
validationQuery="SELECT 1 AS dbcp_connection_test"/>

最近,我的日志中出现错误:

MySQLNonTransientConnectionException:连接太多

所以我检查了发生错误时我有多少连接(通过 Amazon CloudWatch for RDS。特别是“ConnectionCount”),它可以达到高达 150 个连接。如果我将maxTotal 连接数设置为 100,这怎么可能?

我在多个实例上运行我的应用程序。 maxTotal 属性是否适用于每个实例(例如:如果我在 2 个实例上定义了连接池,那么我的 maxTotal = 100 + 100 = 200?)

好像我在Resource 元素中设置的属性被忽略了。可能是我的设置有问题吗?我没有像我想象的那样使用tomcat DBCP吗?

此外,如果我进一步查看上面引用的 Exception 的 StackTrack,我会看到

org.apache.tomcat.dbcp.dbcp2.BasicDataSource.getConnection

被调用。我不确定这是否意味着我使用的连接池 (DBCP2) 与我假设使用的连接池 (Tomcat DBCP) 不同。

【问题讨论】:

  • 你用的是哪个版本的tomcat?
  • @Selaron Tomcat 8.0.43 版(我更新了问题以包含这个)。
  • 确保您只考虑“已建立”的连接。
  • @LuisMuñoz 在哪里?在我的Resource 元素属性中?或者当我计算连接数时?
  • 计算连接数时。

标签: tomcat jdbc connection-pooling jdbc-pool tomcat-dbcp


【解决方案1】:

maxTotal 属性是否适用于每个实例(例如:如果我在 2 个实例上定义了连接池,那么我的 maxTotal = 100 + 100 = 200?)

这是正确的,因为您已在 context.xml 文件中定义了您的 &lt;Resource&gt;。
在 server.xml 中添加您的资源以使其可用于所有上下文,并确保将其从所有 context.xml 文件中删除。记下您的配置中不存在的 global 属性

<GlobalNamingResources>
    <Resource
        global="jdbc/[dbName]"

        factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
        auth="Container" 
        driverClassName="com.mysql.jdbc.Driver"  
        logAbandoned="false" 
        maxTotal="100" 
        maxIdle="30" 
        maxWaitMillis="10000" 
        name="jdbc/[dbName]" 
        password="${dbPassword}" 
        removeAbandonedOnBorrow="true" 
        removeAbandonedTimeout="60" 
        type="javax.sql.DataSource" 
        url="[dbUrl]autoReconnect=true" 
        username="${dbUsername}" 
        testWhileIdle="true" 
        testOnBorrow="true" 
        validationQuery="SELECT 1 AS dbcp_connection_test"/>
</GlobalNamingResources>

关注:

  • testOnBorrow="true" 导致的性能损失并不总是值得的。

  • testWhileIdle="true" 与 timeBetweenEvictionRunsMillis 相关,默认为 5 秒。在某些情况下,默认值可能太短。

  • 验证 AWS RDS 配额为 not exceeded。

【讨论】:

  • 1) 对于所有实例,连接数仍然攀升至高于 MaxTotal 的总和。 2) 我不熟悉global 属性,你能提供一个描述该属性的文档的链接吗?
  • 1) 检查连接的源 IP 以确保所有都来自您的应用程序。我建议在应用程序主机上计算 ESTABLISHED 连接并进行比较。 2)GloblaNamingResources
猜你喜欢
  • 1970-01-01
  • 2019-09-25
  • 1970-01-01
  • 1970-01-01
  • 2012-09-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-04
  • 2013-05-24
相关资源
最近更新 更多