Tomcat JDBC连接池(Tomcat 9)

2020-09-07  本文已影响0人  CokeCode

通用配置项

配置项 描述
factory 必需,且值需要是org.apache.tomcat.jdbc.pool.DataSourceFactory表示使用Tomcat JDBC连接池
type 指定创建的数据源类型,只能是javax.sql.DataSourcejavax.sql.XADataSource之一
defaultAutoCommit (boolean)该数据源创建的连接的默认自动提交属性,如果没有设置,不会调用Connection#setAutoCommit,连接的自动提交属性取决于底层的数据库驱动
defaultReadOnly (boolean)该数据源创建的连接的默认只读属性,如果没有设置,不会调用Connection#setReadOnly,连接的默认只读属性取决于底层的数据库驱动,注意有的驱动不支持只读模式,如Informix
defaultTransactionIsolation (String) 该连接池床架你的连接的默认事务隔离级别,取值为如下的可选值之一:NONEREAD_COMMITTEDREAD_UNCOMMITTEDREPEATABLE_READSERIALIZABLE。如果没有设置,连接的默认事务隔离级别取决于数据库驱动
defaultCatalog (String) The default catalog of connections created by this pool.
driverClassName (String) 使用的JDBC驱动类的全类名,驱动类需要是加载tomcat-jdbc.jar的类加载器可以获取的. 如:oracle.jdbc.OracleDrivercom.mysql.cj.jdbc.Driver(MySQL 8)和com.mysql.jdbc.Driver(MySQL 8以前)
username 用户名
password 密码
maxActive (int)最大连接数,默认100
maxIdle (int)最大空闲连接数,默认为maxActive:100
minIdle (int)最小空闲连接数,默认为initialSize:10
initialSize (int)连接池创建时的初始连接数,默认:10
maxWait (int)从该连接池中等待获取连接的超时上限,单位:毫秒,默认:30000(30秒),获取连接超时连接池将抛出异常
testOnBorrow (boolean)每次获取连接时是否检测连接有效性,失效的连接将被连接池丢弃,默认为false
testOnConnect (boolean) 创建连接时测试连接的有效性,验证失败时抛出SQLException,默认为false
testOnReturn (boolean)每次归还连接的时候是否检测连接的有效性,默认为false
testWhileIdle 是否开启空闲清理线程,默认为false,一旦开启,连接池将会定期检测空闲连接
validationQuery 验证连接使用的SQL,Oracle为select 1 from dual, MySQL为select 1
validationQueryTimeout 验证SQL的执行超时上限,单位:秒,为负数表示关闭连接验证超时,默认-1
validatorClassName (String) 实现 org.apache.tomcat.jdbc.pool.Validator接口并提供无参构造方法的实现类,用来替代连接验证SQL,对连接进行验证。默认为null,示例如:com.mycompany.project.SimpleValidator
timeBetweenEvictionRunsMillis (int) 空闲连接清理线程运行的间隔时间,单位:毫秒。该值应该大于1秒,默认5000(5秒)
minEvictableIdleTimeMillis (int) 连接被回收前可以空闲的最小时间,单位:毫秒。默认值:60000(60秒)
removeAbandoned (boolean) 是否移除抛弃的(abandoned)连接,一个连接使用超过了removeAbandonedTimeout上限就被视为抛弃的,开启该开关可以恢复那些应用没有关闭的连接。默认为false
removeAbandonedTimeout (int) 单位:秒,一个连接使用超过多久就视为抛弃的(abandoned),默认为60 秒(60 seconds). 该值应该超过你的应用中最长的SQL可能运行的时间
logAbandoned (boolean) 记录抛弃连接的应用的堆栈信息,默认false,会增加系统开销,因为为了能够在可能发生的连接被抛弃时记录堆栈 ,应用每次获取连接时都需要生成堆栈信息
connectionProperties (String) 创建新的连接时传给JDBC驱动的连接属性,格式必须是[propertyName=property;]*,注意userpassword参数会被显式传递,因此无需再这里再次指定,默认为null
accessToUnderlyingConnectionAllowed tomcat-jdbc未使用
numTestsPerEvictionRun tomcat-jdbc未使用
poolPreparedStatements tomcat-jdbc未使用
maxOpenPreparedStatements tomcat-jdbc未使用

连接检查相关选项

连接检查检查连接的有效性,清理失效的连接

注意:

testOnBorrow并不适合高负载的系统,将会导致每次获取连接都增加一次查询请求,带来额外负载。
高负载系统可以考虑使用testWhileIdle,在空闲时检测连接;
testOnReturn一般用处不大。

清理线程相关选项

当启动evictor线程后,如果连接数小于minIdle,则创建新的连接直到minIdle个数,没有启动evictor线程时,minIdle没有意义;

无论是否开启evictor线程,当业务压力增加时,活跃连接数可能超过maxIdle,但不会超过maxActive;活跃连接数超过maxIdle时,使用完的活跃连接归还时会立即关闭;

在没有开启evictor线程,假设活跃连接个数曾经超过maxIdle接近或达到maxActive,当压力变小,使用中的连接数降低时,假设最终所有连接都空闲下来时,这时空闲连接将维持在maxIdle因为此时没有evictor线程。

开启evictor线程后,上述的场景,evictor线程每隔timeBetweenEvictionRunsMillis检测空闲,如果连接空闲超过minEvictableIdleTimeMillis,则清理空闲连接,最终使空闲连接维持在minIdle

可见当maxActive大于maxIdle时,活跃连接超过maxIdle后归还就会被关闭,再获取时如果没有可用连接,总连接数又小于maxActive时,又会新建连接,因此这种情况会带来连接池伸缩造成的性能开销,因此推荐配置maxActive等于maxIdle避免连接池伸缩开销。

initialSize是在连接池创建时的初始连接个数,如果启动evictor且initialSize小于minIdle,则evictor会创建空闲连接将连接数维持在minIdle;如果没有开启evictor,则只有连接使用请求上升时,才会在initialSize基础上创建新的连接。

Abandoned连接选项

Abandoned连接指应用长时间未归还给连接池的连接,连接池可以自动关闭这些连接,以防止连接泄漏。相关配置项如下,具体释义见上表。

注意对于长时间使用同一连接进行批量操作的场景可能不适用该功能。

removeAbandonedTimeout必须长于应用可能的最长SQL执行时间,否则SQL尚未完成执行,连接就被关闭,因此长时间使用同一连接进行批量操作的场景应谨慎使用该功能。

系统配置项

配置项 含义
org.apache.tomcat.jdbc.pool.onlyAttemptCurrentClassLoader

Tomcat JDBC 增强配置项

配置项 含义
initSQL
jdbcInterceptors
validationInterval
jmxEnabled
fairQueue
abandonWhenPercentageFull
maxAge
useEquals
suspectTimeout
rollbackOnReturn
commitOnReturn
alternateUsernameAllowed
dataSource
dataSourceJNDI
useDisposableConnectionFacade
logValidationErrors
propagateInterruptState
ignoreExceptionOnPreLoad
useStatementFacade

Spring Boot中使用Tomcat JDBC连接池

基于Spring Boot 2.x,直接将tomcat-jdbc加入依赖:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>com.zaxxer</groupId>
                    <artifactId>HikariCP</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jdbc</artifactId>
        </dependency>

在应用中使用配置类创建DataSource类型的Bean:

    @Bean
    @ConfigurationProperties("your.datasource.prefix")
    public DataSource dataSource() {
        return DataSourceBuilder.create().type(org.apache.tomcat.jdbc.pool.DataSource.class).build();
    }

Spring Boot使用Tomcat JDBC作为Tomcat JNDI连接池

Tomcat中也带有Tomcat JDBC的jar,但是默认TOMCAT JNDI使用DBCP连接池,如果使用Tomcat JDBC作为Tomcat JNDI的连接池实现,那么就必须在配置中显式指定factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"

在Tomcat安装目录下的conf/目录中增加context.xml文件:

<?xml version='1.0' encoding='utf-8'?>
<Context useHttpOnly="true" privileged="true" reloadable="true">
    <Resource name="jdbc/TestDB"
          auth="Container"
          type="javax.sql.DataSource"
          factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
          testWhileIdle="true"
          testOnBorrow="true"
          testOnReturn="false"
          validationQuery="SELECT 1"
          validationInterval="30000"
          timeBetweenEvictionRunsMillis="30000"
          maxActive="100"
          minIdle="10"
          maxWait="10000"
          initialSize="10"
          removeAbandonedTimeout="60"
          removeAbandoned="true"
          logAbandoned="true"
          minEvictableIdleTimeMillis="30000"
          jmxEnabled="true"
          jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;
            org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
          username="root"
          password="password"
          driverClassName="com.mysql.cj.jdbc.Driver"
          url="jdbc:mysql://localhost:3306/mysql"
    />
</Context>

在配置类中通过JNDI查询获取相应的DataSource实例:

@Bean
public DataSource jndiDataSource() {
    JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
    DataSource dataSource = dataSourceLookup.getDataSource("jdbc/TestDB");
    return dataSource;
}

连接Oracle 12c:

  1. 驱动
<dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc6</artifactId>
</dependency>
  1. 驱动类oracle.jcbc.OracleDriver
  2. 连接串:jdbc:oracle:thin:@IP:PORT:SID
  3. 连接验证SQL:select 1 from dual

连接MySQL 8

  1. 驱动
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.18</version>
</dependency>
  1. 驱动类com.mysql.cj.jdbc.Driver
  2. 连接串:jdbc:mysql://IP:PORT/DB_NAME
  3. 连接验证SQL:select 1
上一篇下一篇

猜你喜欢

热点阅读