gpt4 book ai didi

java - 如何记录Tomcat 7 JDBC连接池、连接创建

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:46:51 24 4
gpt4 key购买 nike

尽管我们使用的是 Tomcat 7 JDBC 连接池,但我正在尝试调试似乎打开和关闭的数据库连接数量过多。当在数据源上调用 getConnection() 导致打开新连接而不是从池中借用现有连接时,我该如何记录?

最佳答案

我知道有两种查看 Tomcat 数据库连接池信息的方法。

1.使用JMX监控

默认情况下,Tomcat 连接池会将自己注册为 MBean(JMX Bean)。可以使用 tomcat-jdbc-pool 上的 jmxEnabled 属性打开/关闭此功能。参见 The Tomcat JDBC Connection Pool .

您可以使用各种外部 JMX 工具来监控数据库连接池和其他 JMX 资源。我建议从 Java 附带的 JConsole 开始。启动 JConsole,连接到您的 Tomcat (Catalina) JVM,选择 MBeans header ,打开 Catalina/DataSource/... 参见下图。

JConsole showing DataSource / DB Connection Pool

阅读更多关于 Monitoring Tomcat 的信息.

2. 写一个JdbcInterceptor 类记录数据库连接池信息

Tomcat 连接池允许您为 JDBC 连接注册拦截器。下面,我将展示如何写一个 JdbcInterceptor记录连接使用情况的类。该示例适用于 Tomcat 8,但它也可能适用于 Tomcat 7。

tomcat-jdbc.jar 添加为项目的依赖项。

    <dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
<version>8.0.8</version>
<scope>provided</scope>
</dependency>

创建一个 JdbcInterceptor 类

此类使用公共(public)日志记录,您可能想使用其他东西。

package com.acme.rest.config;

import java.lang.reflect.Method;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tomcat.jdbc.pool.ConnectionPool;
import org.apache.tomcat.jdbc.pool.JdbcInterceptor;
import org.apache.tomcat.jdbc.pool.PooledConnection;

public class MyConnectionPoolLogger extends JdbcInterceptor {

private static final Log log = LogFactory.getLog(MyConnectionPoolLogger.class);

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (log.isDebugEnabled()) {
String name = method.getName();
if (CLOSE_VAL.equals(name)) {
log.debug(String.format("Returning Connection to Pool [%s]", proxy));
}
}
return super.invoke(proxy, method, args);
}

@Override
public void reset(ConnectionPool connPool, PooledConnection conn) {
if (connPool != null && conn != null) {
if (log.isDebugEnabled()) {
log.debug(String.format("Getting Connection [%s], Pool active=[%s], idle=[%s]", conn.toString(),
connPool.getActive(), connPool.getIdle()));
}
}
}

@Override
public void disconnected(ConnectionPool connPool, PooledConnection conn, boolean finalizing) {
if (connPool != null && conn != null) {
if (log.isDebugEnabled()) {
log.debug(String.format("Closing Connection [%s], Pool active=[%s], idle=[%s]", conn.toString(),
connPool.getActive(), connPool.getIdle()));
}
}
}
}

在Context.xml中注册这个拦截器类

<Context>
<Resource
name="jdbc/acmedb"
auth="Container"
type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"

jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;
org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;
com.acme.rest.config.MyConnectionPoolLogger"

/>
</Context>

JdbcInterceptor 类可以注册为 Resource ,如上所示,或作为 POJO .

日志样本

下面是访问连接池时Tomcat的一些示例日志

2017-11-04 00:15:19,389 DEBUG Getting Connection [PooledConnection[com.mysql.jdbc.JDBC4Connection@6dea96f]], Pool active=[1], idle=[0]
2017-11-04 00:15:19,393 DEBUG Returning Connection to Pool [ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@6dea96f]]]
2017-11-04 00:16:19,249 DEBUG Closing Connection [PooledConnection[com.mysql.jdbc.JDBC4Connection@6dea96f]], Pool active=[0], idle=[1]

关于java - 如何记录Tomcat 7 JDBC连接池、连接创建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25917773/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com