16

在 DBCP 中出现连接泄漏和死锁问题后,我们决定将其替换为 Tomcat JDBC 池。当然,迁移真的很简单。

但在将其部署到生产环境后,我注意到,运行两个 Tomcat 的服务器上的负载从 4-4.5 增加到 5.5。除了更换游泳池外,我们没有再做任何事情。此外,使用 JMeter 测量的性能下降了约 5%。

我花了一些时间调整池参数,但没有明显的效果。我在下面粘贴了我当前的配置(来自<GlobalNamingResources>in server.xml):

<Resource name="jdbc/xxxxxx"
          auth="Container"
          type="javax.sql.DataSource"
          factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
          initialSize="10"
          maxActive="100"
          minIdle="10"
          maxIdle="50"
          maxWait="10000" 
          testOnBorrow="true"
          testOnReturn="false"
          testOnConnect="false"
          testWhileIdle="false"
          validationQuery="SELECT 1 from dual"
          validationInterval="30000"
          suspectTimeout="60"
          timeBetweenEvictionRunsMillis="30000"
          removeAbandonedTimeout="60"
          removeAbandoned="true"
          logAbandoned="true"
          abandonWhenPercentageFull="50"
          minEvictableIdleTimeMillis="60000"
          jmxEnabled="true"
          username="xxxxx"
          password="xxxxx"
          driverClassName="oracle.jdbc.OracleDriver"
          url="jdbc:oracle:oci:xxxxx"/>

FairQueue 和 PoolSweeperEnabled 为 true

在 Spring applicationContext-jdbc.xml 我只有:

  <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="resourceRef">
      <value>true</value>
    </property>
    <property name="jndiName">
      <value>java:comp/env/jdbc/PortalDB</value>
    </property>
  </bean>

我究竟做错了什么?我想,JDBC_pool 应该比开箱即用的 DBCP 更快。

4

2 回答 2

1

您的设置和调整显示正确。您的负载增加可能是由于服务器同时处理更多并发请求。DBCP 可能已阻止服务器承担此负载,因为它锁定池的所有线程。jdbc-pool 不这样做,所以现在您增加了并发性。如果负载增加,响应可能会减少,但您的吞吐量会增加。

我会开始调整

maxActive

匹配您的 maxThreads 以处理并发性。

于 2014-02-10T20:35:48.993 回答
0

您的诊断很奇怪:AFAIK Tomcat 的 DBCP 库只是 commons-dbcp 的重新打包版本......因此从一个更改为另一个不应导致行为或性能发生任何变化。(见这里

不过,您使用的版本可能发生了变化:尤其要注意 1.3/1.4 的差异。(见这里

无论如何,您的配置似乎没问题(尽管您可能会遇到问题,但它确实有效)。更新您的库可能是在不进入调试模式的情况下解决问题的唯一方法......

更进一步,您能否更具体地说明“DBCP 中的连接泄漏和死锁问题”是什么意思?确定死锁和连接池之间存在联系是一个非常精确的诊断:您是怎么得出这个结论的?您可能会遇到死锁,因为您的 SQL 语句很容易发生死锁,而池只能通过同时提供许多连接来实现死锁——这实际上只是它的工作。

于 2013-03-04T13:07:23.567 回答