我的tomcat池设置有什么问题? MaxIdle似乎不起作用

时间:2018-09-03 12:20:02

标签: postgresql tomcat connection-pooling

服务器上的Postgresql状态显示的空闲数大于在Tomcat中配置的空闲数

systemctl status postgresql-9.4.service | grep idle -c
284

换句话说:

select count(state) from pg_stat_activity where state like 'idle' 
284

我的context.xml中的设置是:

<?xml version="1.0" encoding="UTF-8"?>
<Context  allowCasualMultipartParsing="true">
    <Resource 
               name="jdbc/postgres" 
               auth="Container"
               type="javax.sql.DataSource" 
               driverClassName="org.postgresql.Driver"
               url="jdbc:postgresql://localhost:5432/db1"
               username="postgres" password="*****" 
               initialSize ="30"
               maxTotal="300" maxIdle="20" maxWaitMillis="30000"
               closeMethod="close"
               validationQuery="SELECT 1"
               validationQueryTimeout="5"
               removeAbandonedOnBorrow="true"
               removeAbandonedOnMaintenance="true"
               removeAbandonedTimeout="60"
               logAbandoned="true"
      />

          <Resource 
               name="jdbc/postgresDb2" 
               auth="Container"
               type="javax.sql.DataSource" 
               driverClassName="org.postgresql.Driver"
               url="jdbc:postgresql://localhost:5432/db2"
               username="postgres" password="*****" 
               initialSize ="30"
               maxTotal="300" maxIdle="20" maxWaitMillis="30000"
               closeMethod="close"
               validationQuery="SELECT 1"
               validationQueryTimeout="5"
               removeAbandonedOnBorrow="true"
               removeAbandonedOnMaintenance="true"
               removeAbandonedTimeout="60"
               logAbandoned="true"
      />
</Context>

我的代码中的连接如下:

 public String asignacionMax(String type) throws ModuleException, Exception{      
    Connection conn = null;
    PreparedStatement stmt = null;  
    String accountno="";
    try{
        String query = "select nextval('public.asignacionseq');";
        conn = getConnection("GU");
        stmt = conn.prepareStatement(query);   
        ResultSet rst = stmt.executeQuery();    
        String cnt="";
        if(rst.next()){
            cnt = rst.getString("nextval");
            for(int i=cnt.length();i<9;i++){
                cnt= "0"+cnt;
            }   
        }
        accountno = type+cnt;

    }catch(Exception e){
        throw new Exception(e);
    }finally{
        if (conn != null) {conn.close();}
        if (stmt != null) {stmt.close();}
    }
    return accountno;
}

有关我的系统的信息:

服务器版本:Apache Tomcat / 9.0.5
服务器内置:2018年2月6日21:42:23 UTC
服务器编号:9.0.5.0
操作系统名称:Linux
操作系统版本:3.10.0-693.21.1.el7.x86_64
架构:amd64
JVM版本:1.8.0_161-b14

1 个答案:

答案 0 :(得分:0)

Tomcat jdbc pool定义minEvictableIdleTimeMillis属性,以控制连接必须闲置多长时间才能被收回。

  

minEvictableIdleTimeMillis

     

(int)一个对象在有资格被驱逐之前可能在池中空闲的最短时间。默认值为60000(60秒)。

您的配置未指定此属性,因此默认情况下为60秒。

  

1)在该时间段内应该对空闲连接进行计数,以检查其变化。
  2)定义了两个池,因此在某个时刻它可能具有两倍的空闲连接数。
  3)默认情况下,每5秒检查一次可撤消连接,因此您可以在61秒内每3秒检查一次:

timeout 61 watch -n3 "systemctl status postgresql-9.4.service | grep idle -c | tee idle.log"

idle.log应该包含在此期间找到的值。
问题的另一个方面是,从池的角度确保您的验证方法是正确的,换句话说,如果idle对两种方法的含义相同。