【问题标题】:Tomcat JDBC Pool MetricsTomcat JDBC 池指标
【发布时间】:2017-01-10 12:43:00
【问题描述】:

我正在运行 Tomcat 8.0.29,并且我正在使用 Tomcat 提供的使用 JNDI 资源初始化的 JDBC 池。我正在连接到 Postgres 数据库并使用 9.4 发布的 JDBC 驱动程序。一切正常,我能够连接和执行查询。

我想从我的 java 程序中收集有关连接池的指标。例如,我想知道我当前有多少空闲连接和/或池中有多少连接正在使用中。我尝试提高日志记录级别,但这并没有给我任何这些池指标。我尝试查看 JMX,但没有看到任何具有此信息的 MBean。我确实看到其他一些帖子声称我可以使用 MBean,但我正在运行的版本没有这些 MBean。

我已经搜索了很多,但找不到这个简单问题的答案。我基本上只是想记录或能够查询与 Tomcat 中的 JDBC 池相关的指标。

【问题讨论】:

    标签: tomcat jdbc connection metrics pool


    【解决方案1】:

    我就是这样做的,但是我已经在 Tomcat 7 中测试过,但还没有在 Tomcat 8 中测试过

    首先您必须获得对javax.sql.DataSource 对象的访问权限。如果您能够执行 SQL,这应该不难。获得 DataSource 对象引用后,将其转换为 org.apache.tomcat.dbcp.dbcp.BasicDataSource 应该可以让您获得所需的指标:

    public double testDsUsagePercentage(javax.sql.DataSource ds){
        org.apache.tomcat.dbcp.dbcp.BasicDataSource basic = (org.apache.tomcat.dbcp.dbcp.BasicDataSource)ds;
        int total = basic.getMaxActive();
        int idle = basic.getNumIdle();
        int active = basic.getNumActive();
        double percentage = this.calcUsagePercent(total, active + idle);
        return percentage;
    }
    
    /**
     * 
     * @param max
     * @param used
     * @return
     */
    private double calcUsagePercent(int max, int used){
        if(max == 0){
            return 0.0;
        }
        return ((double)used / (double)max)*100;
    }
    

    【讨论】:

    • 我刚刚在8中尝试过。没有org.apache.tomcat.dbcp.dbcp.BasicDataSource,但是org.apache.tomcat.dbcp.dbcp2.BasicDataSource有一个包名。我改用它并且所有内容都正确编译,但是,在运行时我收到以下错误“严重:org.apache.tomcat.jdbc.pool.DataSource 无法转换为 org.apache.tomcat.dbcp.dbcp2.BasicDataSource”。我最终做了一些不同的事情,但更多的是参与。我会更新我的问题。
    【解决方案2】:

    我最终通过创建自定义 JDBCInterceptor 解决了这个问题。我的拦截器很简单:

        import java.text.SimpleDateFormat;
        import org.apache.tomcat.jdbc.pool.ConnectionPool;
        import org.apache.tomcat.jdbc.pool.JdbcInterceptor;
        import org.apache.tomcat.jdbc.pool.PooledConnection;
    
        public class MetricsInterceptor extends JdbcInterceptor{
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss");
            @Override
            public void reset(ConnectionPool cPool, PooledConnection conn) {
            // TODO Auto-generated method stub
    
            System.out.println("Connection Pool:Pool Size:"+cPool.getSize());
            System.out.println("Connection Pool:Active Count:"+cPool.getActive());
            System.out.println("Connection Pool:Idle Count:"+cPool.getIdle());
            System.out.println("Connection Pool:Wait Count:"+cPool.getWaitCount());
            System.out.println("Connection:ID:"+conn.toString());
            System.out.println("Connection:Last    Validated:"+sdf.format(conn.getLastValidated()));
            System.out.println("Connection:Last Connected:"+sdf.format(conn.getLastConnected()));
            System.out.println("Connection:is Released:"+conn.isReleased());
            System.out.println("Connection:is Suspect:"+conn.isSuspect());
    
        }
    
    }
    

    我将它导出到一个 JAR 中,并将它放在我的 tomcat/lib 目录中。我还更新了我的 context.xml JNDI 数据源以包含我的新拦截器。

    <Resource name="jdbc/postgres" auth="Container"
    ......jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;
                  org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer; **org.mayan.tomcat.jdbc.pool.interceptor.MetricsInterceptor**"/>
    

    当我重新启动 Tomcat 时,我的控制台正在打印出我正在寻找的连接指标。

    希望这对其他人有所帮助。

    【讨论】:

      猜你喜欢
      • 2013-09-04
      • 2012-03-02
      • 1970-01-01
      • 2014-12-26
      • 2014-02-24
      • 2012-11-04
      • 2012-12-08
      • 2017-06-19
      • 1970-01-01
      相关资源
      最近更新 更多