最近公司要用Druid 所以看了下基本配置及配置过程中出现的问题 

Druid是什么?

Druid是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0、DBCP、PROXOOL等DB池的优点,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况,可以说是针对监控而生的DB连接池,据说是目前最好的连接池druid功能最为全面,sql拦截等功能,统计数据较为全面,具有良好的扩展性。

为什么要选druid,主流Java数据库连接池分析

C3p0: 开源的JDBC连接池,实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate、Spring等。单线程,性能较差,适用于小型系统,代码600KB左右。

DBCP (Database Connection Pool):由Apache开发的一个Java数据库连接池项目, Jakarta commons-pool对象池机制,Tomcat使用的连接池组件就是DBCP。单独使用dbcp需要3个包:common-dbcp.jar,common-pool.jar,common-collections.jar,预先将数据库连接放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完再放回。单线程,并发量低,性能不好,适用于小型系统。

Jdbc :Tomcat在7.0以前都是使用common-dbcp做为连接池组件,但是dbcp是单线程,为保证线程安全会锁整个连接池,性能较差,dbcp有超过60个类,也相对复杂。

BoneCP: BoneCP是一个高效、免费、开源的Java数据库连接池实现库。设计初衷就是为了提高数据库连接池性能,根据某些测试数据显示,BoneCP的速度是最快的,要比当时第二快速的连接池快25倍左右,完美集成到一些持久化产品如Hibernate和DataNucleus中。BoneCP特色:高度可扩展,快速;连接状态切换的回调机制;允许直接访问连接;自动化重置能力;JMX支持;懒加载能力;支持XML和属性文件配置方式;较好的Java代码组织,100%单元测试分支代码覆盖率;代码40KB左右。

Druid:Druid是Java语言中最好的数据库连接池,Druid能够提供强大的监控和扩展功能,是一个可用于大数据实时查询和分析的高容错、高性能的开源分布式系统,尤其是当发生代码部署、机器故障以及其他产品系统遇到宕机等情况时,Druid仍能够保持100%正常运行。主要特色:为分析监控设计;快速的交互式查询;高可用;可扩展;Druid是一个开源项目,源码托管在github上。Ps:https://github.com/alibaba/druid

 

Druid简单使用

Druid是一个JDBC组件,它包括三个部分:

    基于Filter-Chain模式的插件体系。

    DruidDataSource :高效可管理的数据库连接池。

    SQLParser :sql语句解析器

 

Maven依赖(最新版本v1.1.20)

<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->

<dependency>

    <groupId>mysql</groupId>

    <artifactId>mysql-connector-java</artifactId>

    <version>8.0.12</version>

</dependency>
<dependency>  
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
<dependency>

    <groupId>com.alibaba</groupId>

    <artifactId>druid</artifactId>

    <version>1.1.5</version>

</dependency>

 

 Application配置文件配置

配置文件配置可选properties和yml两种

# 数据库访问配置

# 主数据源,默认的

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.datasource.url=jdbc:mysql://localhost:3306/druid?serverTimezone=GMT&useSSL=false

spring.datasource.username=root

spring.datasource.password=root

# 下面为连接池的补充设置,应用到上面所有数据源中

# 初始化大小,最小,最大

spring.datasource.druid.initial-size=5

spring.datasource.druid.min-idle=5

spring.datasource.druid.max-active=20

# 配置获取连接等待超时的时间

spring.datasource.druid.max-wait=60000

# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒

spring.datasource.druid.time-between-eviction-runs-millis=60000

# 配置一个连接在池中最小生存的时间,单位是毫秒

spring.datasource.druid.min-evictable-idle-time-millis=300000

#用来检测连接是否有效的sql,要求是一个查询语句。

#如果validationQuery为null,testOnBorrow、testOnReturn、

#testWhileIdle都不会其作用。

spring.datasource.druid.validation-query=SELECT 1 FROM DUAL

#建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于

#timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。

spring.datasource.druid.test-while-idle=true

#申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能

spring.datasource.druid.test-on-borrow=false

#归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能

spring.datasource.druid.test-on-return=false

# 打开PSCache,并且指定每个连接上PSCache的大小

spring.datasource.druid.pooling-connection-info=true

#是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。

spring.datasource.druid.pool-prepared-statements=true


spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20

# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙

spring.datasource.druid.filters=stat,wall,log4j

# 通过connectProperties属性来打开mergeSql功能;慢SQL记录

spring.datasource.druid.connection-properties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

 


 Druid过滤器配置     

DruidFilter 有两种配置 一种是直接使用javax的@WebFilter注解格式

/**

 * Druid过滤器.

 * @author Administrator

 */
@WebFilter(filterName="druidWebStatFilter",urlPatterns="/*",


        initParams={


                @WebInitParam(name="exclusions",value="*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*")//忽略资源

        }


)

public class DruidFilter extends WebStatFilter{

       }

 

FilterRegistrationBean选择其一即可
public class DruidFilter {

        @Bean

        public FilterRegistrationBean druidStatFilter2() {


                FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());


                //添加过滤规则.

                filterRegistrationBean.addUrlPatterns("/*");


                //添加不需要忽略的格式信息.

                filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");

                return filterRegistrationBean;

        }



        }

DruidServlet配置

DruidServlet有两种配置 一种是直接使用javax的@WebFilter注解格式

/**


 * druid数据源状态监控.


 * @author Administrator


 *


 */

    @WebServlet(urlPatterns="/druid/*",


            initParams={


                    @WebInitParam(name="allow",value=""),// IP白名单(没有配置或者为空,则允许所有访问)


                    @WebInitParam(name="deny",value="192.168.1.73"),// IP黑名单 (存在共同时,deny优先于allow)


                    @WebInitParam(name="loginUsername",value="admin"),// 用户名


                    @WebInitParam(name="loginPassword",value="admin"),// 密码


                    @WebInitParam(name="resetEnable",value="false")// 禁用HTML页面上的“Reset All”功能


            }


    )


    public class DruidServlet extends StatViewServlet


    {


        private static final long serialVersionUID = 1L;

    }
ServletRegistrationBean 来注册servlet选择其一即可
@Bean

public ServletRegistrationBean DruidStatViewServle2() {

        //org.springframework.boot.context.embedded.ServletRegistrationBean提供类的进行注册.

        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");


        //添加初始化参数:initParams


        //白名单:

        servletRegistrationBean.addInitParameter("allow", "127.0.0.1");

        //IP黑名单 (存在共同时,deny优先于allow) : 如果满足deny的话提示:Sorry, you are not permitted to view this page.

        servletRegistrationBean.addInitParameter("deny", "192.168.1.73");

        //登录查看信息的账号密码.

        servletRegistrationBean.addInitParameter("loginUsername", "admin2");

        servletRegistrationBean.addInitParameter("loginPassword", "123456");

        //是否能够重置数据.

        servletRegistrationBean.addInitParameter("resetEnable", "false");

        return servletRegistrationBean;

}

**在StatViewSerlvet输出的html页面中,有一个功能是Reset All,执行这个操作之后,会导致所有计数器清零,重新计数。所以一般都设置关闭。


监控配置好后可直接访问

http://loaclhost:port/projectname/druid/index.html

 

上述配置可直接改为yml配置即:

<!-- 直接使用druid可能会导致配置文件不生效没有提示建议使用-->
<!--        <dependency>-->
<!--         <groupId>com.alibaba</groupId>-->
<!--         <artifactId>druid-spring-boot-starter</artifactId>-->
<!--          <version>1.1.10</version>-->
<!--        </dependency>-->
spring:
# 配置数据库信息
  datasource:
druid:
# 数据源配置
      username: root
password: root
url: jdbc:mysql://localhost:3306/druid?serverTimezone=GMT&useSSL=false  # 设置时区
      driver-class-name: com.mysql.cj.jdbc.Driver
# 初始化 最小 最大
      initial-size: 5
      min-idle: 5
      max-active: 300
      # 配置获取连接等待超时的时间
      max-wait: 60000
      # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      time-between-eviction-runs-millis: 60000
      # 配置一个连接在池中最小生存的时间,单位是毫秒
      min-evictable-idle-time-millis: 300000
      validation-query: SELECT 'x' #用来检测连接是否有效的sql,要求是一个查询语句,配置为null则
      test-while-idle: true #建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,空闲时间大于间隔检测时间,执行检测连接是否有效
      test-on-borrow: false #申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
      test-on-return: false #归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
      # 开启PSCache,并且指定每个连接上PSCache的大小,PSCache对支持游标的数据库性能提升巨大,比如oracle。在mysql下建议关闭
      poolPreparedStatements: false
      #值大于0默认开启cache,数据库缓存,同一条sql匹配cache,
      #mysql的cache功能只适用于下列场合:数据变动较少,select较多的table
      maxPoolPreparedStatementPerConnectionSize: 100
      # 配置多个英文逗号分隔
      filters: stat,wall,log4j
# WebStatFilter配置,说明请参考Druid Wiki,配置_配置WebStatFilter
      # 启用StatFilter默认值true
      web-stat-filter:
enabled: true
        url-pattern: /*
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
        session-stat-enable: false
session-stat-max-count: 1000
#        principal-cookie-name: admin
        #        principal-session-name: admin
        profile-enable: true
# http://loacalhsot:8080/druid/index.html
      stat-view-servlet:
url-pattern: /druid/*  # 监控页面访问路径
        reset-enable: false      # 不允许清空统计数据
        login-username: admin    #用户名
        login-password: admin   #密码
        allow: ""                # 白名单
        deny: 192.168.1.244         #黑名单 优先级deny>allow
      #缺省多个DruidDataSource的监控数据是各自独立的,支持配置公用监控数据合并数据源。
      use-global-data-source-stat: true
      connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=20
filter:
log4j:
enabled: true
        stat:
log-slow-sql: true
server:
port: 8080
即可直接访问监控页面 http://localhost:8080/druid/sql.html

FAQ:

1. druid是通过配置Filter拦截JDBC的方法调用,防止sql注入也是在JDBC最低层进行拦截做判断,不会遗漏。   

2. 只有配置filter才能打卡i监控功能,配置servlet才能调用监控页面

3. 数据源不显示,是配置文件statfilter配置没有生效。

4.Druid不依赖任何的log组件,但支持多种log组件,会根据检测当前环境,选择一种合适的log实现,可记录sql日志。

5理论上说,支持所有有jdbc驱动的数据库。

6.如果不适用spring自动加载datasource,sql则无法被监控

7.日志不打印,則druid需要看druid默认的日志和spring日志是否冲突

8.druid 慢sql不打印ylm默认不开启需要手动在statfilter开启log过滤器和注解打印

filter:
        log4j:
          enabled: true
        stat:
          log-slow-sql: true   

9.

 

更新地址https://github.com/alibaba/druid

有什么问题请大家指出,我会尽力修改完善。

 

咱也不懂咱也不敢问呐