数据库连接池

2021/04/21

数据库连接池

参考资料

一、数据库连接池介绍

1.1 为什么要使用数据库连接池

1.2 原理

二、druid

2.1、引入druid

<dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>druid</artifactId>
     <version>1.1.9</version>
</dependency>

2.2、修改dataSource配置

datasource:
    name: dataSource
    url: jdbc:mysql://127.0.0.1:3306/db_test?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      driver-class-name: com.mysql.jdbc.Driver
      filters: stat
      maxActive: 20
      initialSize: 1
      maxWait: 60000
      minIdle: 1
      timeBetweenEvictionRunsMillis: 60000
      minEvictableIdleTimeMillis: 300000
      validationQuery: select 'x'
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      poolPreparedStatements: true
      maxOpenPreparedStatements: 20
      ## Druid StatViewServlet监控配置
      stat-view-servlet:
        enabled: true
        url-pattern: /druid/*
        reset-enable: false
        login-username: admin
        login-password: admin
        allow: 127.0.0.1
        deny:

2.3、访问

http://127.0.0.1:8080/testApp/druid/*

三.工程改druid连接池

druid是阿里出的数据库连接池,该连接池还提供了强大的监控和扩展功能。

关于druid连接池

  • druid是阿里出的数据库连接池,号称java最好连接池。
  • druid针对Oracle和MySql做了特别优化,比如Oracle的PS Cache内存占用优化,MySql的ping检测优化。
  • druid提供了MySql、Oracle、Postgresql、SQL-92的SQL的完整支持,这是一个手写的高性能SQL Parser,支持Visitor模式,使得分析SQL的抽象语法树很方便。 简单SQL语句用时10微秒以内,复杂SQL用时30微秒。
  • 通过Druid提供的SQL Parser可以在JDBC层拦截SQL做相应处理,比如说分库分表、审计等。Druid防御SQL注入攻击的WallFilter就是通过Druid的SQL Parser分析语义实现的。

对比druid、DBCP、c3p0

c3p0的问题

  • 不支持LRU(见下面连接池对比)
  • 连接数管理基本没用
  • 易死锁,通常需将最大最小连接数设为相同,且maxStatements=0,c3p0的bug,换个角度说最大最小始终相同等于没有动态申请连接功能

DBCP的问题

druid的优势

  • druid内置监控统计功能,含监控页面
  • druid提供防SQL注入功能
  • druid支持LRU、ExceptionSorter等特性->连接池对比
  • 国产,目前官方文档已经不错 官方wiki 官方介绍“Druid是一个活跃的项目,长期维护。”,如有问题应该会比较快修复

如何修改(两步即可)

1、引入druid
<dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>druid</artifactId>
     <version>1.1.9</version>
</dependency>

2、修改dataSource
将dataSource的实现类改为DruidDataSource,并配置参数即可。
修改前:
<!-- 数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
  <property name="driverClass">
    <value>${dataSource.driverClass}</value>
  </property>
  <property name="jdbcUrl">
    <value>${dataSource.jdbcUrl}</value>
  </property>
  <property name="user">
    <value>${dataSource.user}</value>
  </property>
  <property name="password">
    <value>${dataSource.password}</value>
  </property>
  <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
  <property name="acquireIncrement">
    <value>${dataSource.acquireIncrement}</value>
  </property>
  <!--初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
  <property name="initialPoolSize">
    <value>${dataSource.initialPoolSize}</value>
  </property>
  <!--连接池中保留的最大连接数。Default: 15 -->
  <property name="maxPoolSize">
    <value>${dataSource.maxPoolSize}</value>
  </property>
  <!--连接池中保留的最小连接数。 -->
  <property name="minPoolSize">
    <value>${dataSource.minPoolSize}</value>
  </property>
</bean>

修改后:
改为druid配置如下 
<!-- 数据源 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
  <property name="driverClassName" value="${dataSource.driverClass}" ></property>
  <property name="url" value="${dataSource.jdbcUrl}" ></property>
  <property name="username" value="${dataSource.user}"></property>
  <property name="password" value="${dataSource.password}"></property>
  <!-- 配置监控统计拦截的filters -->
  <property name="filters" value="stat" />
  <!-- 配置初始化大小、最小、最大 -->
  <property name="maxActive" value="${dataSource.maxPoolSize}" />
  <property name="initialSize" value="${dataSource.initialPoolSize}" />
  <property name="minIdle" value="${dataSource.minPoolSize}" />
  <!-- 配置获取连接等待超时的时间 -->
  <property name="maxWait" value="60000" />     

  <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
  <property name="timeBetweenEvictionRunsMillis" value="60000" />

  <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
  <property name="minEvictableIdleTimeMillis" value="300000" />

  <property name="testWhileIdle" value="true" />
  <property name="testOnBorrow" value="false" />
  <property name="testOnReturn" value="false" />

  <!-- PSCache,Mysql建议关闭 -->
  <property name="poolPreparedStatements" value="false" />
  <property name="maxOpenPreparedStatements" value="0" />
</bean>

配置监控功能
开启监控
在连接池bean的做如下配置开启监控
<property name="filters" value="stat" />
还可使用proxyFilters配置filter实例,和filters属性是组合关系
监控页面
修改web.xml加监控页面
<!-- druid stat -->
<servlet>
    <servlet-name>DruidStatView</servlet-name>
    <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
    <init-param>
      <param-name>allow</param-name>
      <param-value>安全控制,限制可访问监控页面的ip,逗号分隔</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>DruidStatView</servlet-name>
    <url-pattern>/druid/*</url-pattern>
</servlet-mapping>


可以看到可监控内容还是挺多的,开启web、spring等监控还需加一些配置,见官方文档

SQL监控,可以看到SQL执行时间、更新条数、读取条数,时间分布等多种统计项,可以掌握很多SQL执行相关信息

另外,监控日志可以配置输出到日志,可以通过StatFilter过滤慢SQL进行记录。 推荐项目在遇到SQL问题排查困难时,使用这个连接池并开启监控功能,通过其强大监控统计功能辅助分析
慢SQL记录

使用logback记录日志
数据源增加Filter
    <property name="proxyFilters">  
        <list>  
            <ref bean="stat-filter" />  
            <ref bean="log-filter" />  
        </list>   
    </property>
配置Filter bean
  <!-- druid 慢SQL记录 -->  
  <bean id="stat-filter" class="com.alibaba.druid.filter.stat.StatFilter">  
      <property name="mergeSql" value="true" />  
      <property name="slowSqlMillis" value="10" />  
      <property name="logSlowSql" value="true" />
      <property name="connectionStackTraceEnable" value="true" />
  </bean>  

  <bean id="log-filter" class="com.alibaba.druid.filter.logging.Slf4jLogFilter">  
      <property name="resultSetLogEnabled" value="true" />  
  </bean>

慢SQL是在com.alibaba.druid.filter.stat.StatFilter中输出的,可以在logback中对此类的日志单独输出到一个文件
这个类的输出的信息不是很全面,就是执行时间、sql、参数,比监控页面信息少的多。

Spring 监控
监控spring对象和方法,包括执行次数、执行时间、记录行数等。

需引入aspectjweaver包,并在xml头开启aop命名支持
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.8.13</version>
  </dependency>

spring中基本配置如下
  <!-- druid spring监控 -->
  <bean id="druid-stat-interceptor"
    class="com.alibaba.druid.support.spring.stat.DruidStatInterceptor">
  </bean>
  <bean id="druid-stat-pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut"
     scope="prototype">
     <property name="patterns">
        <list>
           <value>com.wds.adc.*</value>
        </list>
     </property>
  </bean>
  <aop:config>
    <aop:advisor advice-ref="druid-stat-interceptor" pointcut-ref="druid-stat-pointcut" />
  </aop:config>

更多配置参见官网druid wiki

四、hikari

Post Directory

扫码关注公众号:暂无公众号
发送 290992
即可立即永久解锁本站全部文章