Tomcat 中的 JDBC Pool

什么是连接池

什么是 Connection Pool -- 连接池呢?

我就不解释了。不太清楚的看这篇文章 [生产级别Nodejs开发实践-使用连接池](这篇文章的前半部分讲述了什么是连接池)

Tomcat中的jdbc连接池

它的英文文档在:[The Tomcat JDBC Connection Pool]

Tomcat 不仅是非常受欢迎的 Servlet 容器,也是同时为我们提供了很多非常实用组件。 jdbc pool 就是其中一个非常实用且高效的 jdbc 连接池的实现. Tomcat 官方大概列出了15条tomcat相对于其他连接池的优点,我这里就不在详细解释了。

jdbc pool 组件存在于 tomcat8 release 版本的 lib/tomcat-jdbc.jar 包中。

我们所使用的到所有类都存在于 org.apache.tomcat.jdbc.pool 包名下。

依赖

这里面我们以 mysql 作为数据库来演示

添加 mysql-connector 依赖

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.34</version>
</dependency>

当然也少不了我们的 tomcat-jdbc

<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-jdbc</artifactId>
    <version>8.0.15</version>
</dependency>

要注意的是 tomcat-jdbc 依赖 tomcat-juli 包,这个包是在tomcat中的日志框架。几乎被所有tomcat包所依赖。如果使用maven安装依赖的话,就不用理会,因为是会被自动安装的,如果单独下载jar包的话,还是要下载这个jar包到CLASS_PATH

用代码来描述

废话到这儿,该上点代码了。 怎么创建一个 jdbc 连接池池实例呢?

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.tomcat.jdbc.pool.DataSource;
import org.apache.tomcat.jdbc.pool.PoolProperties;

// main
// 创建连接池属性对象
PoolProperties poolProps = new PoolProperties();
poolProps.setUrl("jdbc:mysql://localhost:3306/test");

poolProps.setDriverClassName("com.mysql.jdbc.Driver");

poolProps.setUsername("root");

poolProps.setPassword("123456");

// 创建连接池, 使用了 tomcat 提供的的实现,它实现了 javax.sql.DataSource 接口
DataSource dataSource = new DataSource();
// 为连接池设置属性
dataSource.setPoolProperties(poolProps);

try (Connection conn = dataSource.getConnection()) {

    PreparedStatement state = conn.prepareStatement("select * from book");

    ResultSet result = state.executeQuery();

    StringBuilder stringBuilder = new StringBuilder();

    while ( result.next() ) {
            stringBuilder.append("[ id: "+ result.getInt("id") + ", ").append("name: " + result.getString("name") + ",\t").append("publisher: " + result.getString("publisher")).append(" ]\n");
    }

    System.out.println(stringBuilder.toString());

}
catch (SQLException e)
{
    e.printStackTrace();
}

通过代码可以看出,连接池的创建很简单。PoolProperties 类是管理着连接池属性。我们配置连接池,都是通过这个类。

来看看这个类的属性,以下有 50 个属性,来控制着连接池和池中的连接的工作状态和生命周期。接下来我会对常用的属性进行解释。

    private volatile Properties dbProperties = new Properties();
    private volatile String url = null;
    private volatile String driverClassName = null;
    private volatile Boolean defaultAutoCommit = null;
    private volatile Boolean defaultReadOnly = null;
    private volatile int defaultTransactionIsolation = DataSourceFactory.UNKNOWN_TRANSACTIONISOLATION;
    private volatile String defaultCatalog = null;
    private volatile String connectionProperties;
    private volatile int initialSize = 10;
    private volatile int maxActive = DEFAULT_MAX_ACTIVE;
    private volatile int maxIdle = maxActive;
    private volatile int minIdle = initialSize;
    private volatile int maxWait = 30000;
    private volatile String validationQuery;
    private volatile int validationQueryTimeout = -1;
    private volatile String validatorClassName;
    private volatile Validator validator;
    private volatile boolean testOnBorrow = false;
    private volatile boolean testOnReturn = false;
    private volatile boolean testWhileIdle = false;
    private volatile int timeBetweenEvictionRunsMillis = 5000;
    private volatile int numTestsPerEvictionRun;
    private volatile int minEvictableIdleTimeMillis = 60000;
    private volatile boolean accessToUnderlyingConnectionAllowed = true;
    private volatile boolean removeAbandoned = false;
    private volatile int removeAbandonedTimeout = 60;
    private volatile boolean logAbandoned = false;
    private volatile String name = "Tomcat Connection Pool["+(poolCounter.addAndGet(1))+"-"+System.identityHashCode(PoolProperties.class)+"]";
    private volatile String password;
    private volatile String username;
    private volatile long validationInterval = 30000;
    private volatile boolean jmxEnabled = true;
    private volatile String initSQL;
    private volatile boolean testOnConnect =false;
    private volatile String jdbcInterceptors=null;
    private volatile boolean fairQueue = true;
    private volatile boolean useEquals = true;
    private volatile int abandonWhenPercentageFull = 0;
    private volatile long maxAge = 0;
    private volatile boolean useLock = false;
    private volatile InterceptorDefinition[] interceptors = null;
    private volatile int suspectTimeout = 0;
    private volatile Object dataSource = null;
    private volatile String dataSourceJNDI = null;
    private volatile boolean alternateUsernameAllowed = false;
    private volatile boolean commitOnReturn = false;
    private volatile boolean rollbackOnReturn = false;
    private volatile boolean useDisposableConnectionFacade = true;
    private volatile boolean logValidationErrors = false;
    private volatile boolean propagateInterruptState = false;
    private volatile boolean ignoreExceptionOnPreLoad = false;

url, driverClassName, username, password 这些属性知道jdbc的同学,我就不解释了。

  • name 连接池的名称
  • defaultAutoCommit 指定由连接池所创建的连接的自动提交(auto-commit)状态。
  • DefaultReadOnly 由连接池所创建的连接对数据库的只读属性
  • DefaultTransactionIsolation

    指定由连接池所创建的连接的事务级别(TransactionIsolation)。可用值为下列之一:(详情可见javadoc)
    NONE, READ_COMMITTED, READ_UNCOMMITTED, REPEATABLE_READ, SERIALIZABLE

  • MinEvictableIdleTimeMillis
  • JmxEnabled
    开启jmx的管理功能
  • TestWhileIdle
    会使用测试线程,测试池中连接是否能够正常使用。
  • ValidationQuery

    指定连接进入空闲状态时是否经过空闲对象驱逐进程的校验(如果存在空闲对象驱逐进程)。如果校验未通过,则该连接被连接池断掉。

    注意:要想值为true时该设置生效,则validationQuery参数必须为一个非空字串。

  • TestOnBorrow

    指定连接被调用时是否经过校验。如果校验未通过,则该连接被连接池断掉,并由连接池尝试调用另一个连接。

    指定连接返回到池中时是否经过校验。

    注意:要想值为true时该设置生效,则validationQuery参数必须为一个非空字串。

  • TestOnReturn

    指定连接返回到池中时是否经过校验。

    注意:要想值为true时该设置生效,则validationQuery参数必须为一个非空字串。

  • ValidationInterval
    以毫秒为单位验证时间间隔。
  • TimeBetweenEvictionRunsMillis
    以毫秒表示的空闲对象驱逐进程由运行状态进入休眠状态的数值。值为非正数时表示不运行任何空闲对象驱逐进程。
  • MaxActive
    池中 工作连接的最大个数,此值为非正数是表述不限制
  • InitialSize
    以毫秒表示的当连接池中没有可用连接时等待可用连接返回的时间,超时则抛出异常,值为-1时无限期等待。
  • MaxWait
    以毫秒表示的当连接池中没有可用连接时等待可用连接返回的时间,超时则抛出异常,值为-1时无限期等待。
  • MinIdle
    池中最小空闲连接数,当连接数少于此值时,池会创建连接来补充到该值的数量
  • MaxIdle
    池中允许的最大连接数,值为非正数时表示不限制
  • NumTestsPerEvictionRun
    连接池检查每个空闲对象驱逐进程的对象数量(如果存在空闲对象驱逐进程)
  • MinEvictableIdleTimeMillis
    以毫秒表示的连接被空闲对象驱逐进程驱逐前在池中保持空闲状态的最小时间(如果存在空闲对象驱逐进程)。
  • LogAbandoned

    当清除无效连接时是否在日志中记录清除信息的标志。 记录无效的语句和连接,并附加每个连接开启或新建一个语句的系统开销。如果你启用了“removeAbandoned”,可能会导致被设为无效的连接被连接池回收。

    这个机制将会在满足下列两个条件时启动:(getNumIdle() < 2) 和 (getNumActive() > getMaxActive() - 3)

    例如:假设maxActive=20,而当前已经拥有18个活动连接,1个空闲连接,“removeAbandoned”机制将会启动。
    但是只有在活动连接没有使用的时长超过“removeAbandonedTimeout”(默认为300秒)的连接被清除。在遍历结果集时,所使用的连接不会被标为活动连接。

  • RemoveAbandoned

    是否清除已经超过“removeAbandonedTimout”设置的无效连接。

    如果值为“true”则超过“removeAbandonedTimout”设置的无效连接将会被清除。设置此属性可以从那些没有合适关闭连接的程序中恢复数据库的连接。

    记录无效的语句和连接,并附加每个连接开启或新建一个语句的系统开销。

  • RemoveAbandonedTimeout
    以秒表示的清除无效连接的时限。
  • JdbcInterceptors

    设置 tomcat jdbc 连接池的拦截器。

    内置的拦截器: org.apache.tomcat.jdbc.pool.interceptor.ConnectionState

    追踪自动提交、只读状态、catalog和事务隔离等级等状态

org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer
追踪打开的statement,当连接被归还时关闭它们.

多个拦截器用;分割,例如:

poolProps.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");
  • dataSourceJNDI

    指定一个 jndi 作为数据源

  • accessToUnderlyingConnectionAllowed

以上属性当你我无法理解的时候,最好保持默认值。

以下待续。。。

时间: 05-05

Tomcat 中的 JDBC Pool的相关文章

Tomcat JDBC Pool使用说明

Maven依赖 <dependency>   <groupId>org.apache.tomcat</groupId>   <artifactId>tomcat-jdbc</artifactId>   <version>8.5.9</version> </dependency> 最新版本为9.0,推荐使用8.5.9稳定版 常用配置 连接池配置项很多,下面只列出了推荐配置,项目组可根据自身情况进行增减 <b

使用 Tomcat 7 新的连接池 —— Tomcat jdbc pool

Tomcat 在 7.0 以前的版本都是使用 commons-dbcp 做为连接池的实现,但是 dbcp 饱受诟病,原因有: dbcp 是单线程的,为了保证线程安全会锁整个连接池 dbcp 性能不佳 dbcp 太复杂,超过 60 个类 dbcp 使用静态接口,在 JDK 1.6 编译有问题 dbcp 发展滞后 因此很多人会选择一些第三方的连接池组件,例如 c3p0 , bonecp, druid (@wenshao ) 等. 为此,Tomcat 从 7.0 开始引入一个新的模块:Tomcat j

Tomcat7 新的数据库连接池Tomcat jdbc pool介绍和配置

Tomcat 在 7.0 以前的版本都是使用commons-dbcp做为连接池的实现,但是 dbcp存在一些问题: (1)dbcp 是单线程的,为了保证线程安全会锁整个连接池 (2)dbcp 性能不佳 (3)dbcp 太复杂,超过 60 个类,发展滞后. 因此,通常J2EE中还会使用其它的高性能连接池,如 C3P0,还有阿里系的 druid 等.为此,Tomcat 从 7.0 开始引入一个新的模块: Tomcat jdbc pool tomcat jdbc pool 近乎兼容 dbcp ,性能更

JNDI在Tomcat中的配置

使用JNDI获取连接对象 java:comp/env/jdbc/news 这段为固定写法java:comp/env/ 在Tomcat中的配置 配置在:context.xml文件内 F:\apache-tomcat-7.0.68-windows-x64\apache-tomcat-7.0.68\conf\context.xml ---------mySQL<Resource name="jdbc/news"auth="Container" type="

使用 CAS 在 Tomcat 中实现单点登录

单点登录(Single Sign On , 简称 SSO )是目前比较流行的服务于企业业务整合的解决方案之一, SSO 使得在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统.CAS(Central Authentication Service)是一款不错的针对 Web 应用的单点登录框架,本文介绍了 CAS 的原理.协议.在 Tomcat 中的配置和使用,对于采用 CAS 实现轻量级单点登录解决方案的入门读者具有一定指导作用. CAS 介绍 CAS 是 Yale 大学发起的一

CAS 在 Tomcat 中实现单点登录

单点登录(Single Sign On , 简称 SSO )是目前比较流行的服务于企业业务整合的解决方案之一, SSO 使得在多个应用系统 中,用户只需要登录一次就可以访问所有相互信任的应用系统.CAS(Central Authentication Service)是一款不错的针 对 Web 应用的单点登录框架,本文介绍了 CAS 的原理.协议.在 Tomcat 中的配置和使用,对于采用 CAS 实现轻量级单点登录解决方案 的入门读者具有一定指导作用. CAS 介绍 CAS 是 Yale 大学发

用JAXWS-RI在Tomcat中发布WebService

JDK中已经内置了Webservice发布,不过要用Tomcat等Web服务器发布WebService,还需要用第三方Webservice框架.Axis2和CXF是目前最流行的Webservice框架,这两个框架各有优点,不过都属于重量级框架. JAXWS-RI是JAX WebService参考实现.相对于Axis2和CXF,JAXWS-RI是一个轻量级的框架.虽然是个轻量级框架,JAXWS-RI也提供了在Web服务器中发布Webservice的功能.官网地址https://jax-ws.jav

记tomcat中虚拟主机的配置

在开发的时候都是直接把war包直接扔到tomcat的webapps目录下,通过localhost:8080/project来访问,但是在上线系统的部署,显然不可能通过www.xxx.com/project这样去访问的. 原来天真的认为域名是可以指向IP:端口/project这样的,今天去客户那部署发现完全不是那么回事,域名只能指向IP,于是马上求助度娘,找到如下方案. 在tomcat的conf/server.xml中,默认有个节点是 <Host name="localhost" 

Tomcat中部署网站和绑定域名

在安装的tomcat的文件夹下有个conf文件夹 下面有个server.xml文件, 1. 使用80端口 默认tomcat用的是8080端口. <Connector port="8080" protocol="HTTP/1.1"               connectionTimeout="20000"               redirectPort="8443" /> 把这个节点的8080修改成80端口