什么是Druid
Druid是Java语言中最好的数据库连接池。Druid能够提供强大的监控和扩展功能。
Druid也是配置最简单使用最方便的一种连接池。
Druid是阿里巴巴开源平台上的一个项目,整个项目由数据库连接池、插件框架和SQL解析器组成。该项目主要是为了扩展JDBC的一些限制,可以让程序员实现一些特殊的需求,比如向密钥服务请求凭证、统计SQL信息、SQL性能收集、SQL注入检查、SQL翻译等,程序员可以
Druid配置过程
- 加入maven依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>最新版本</version>
</dependency>
- 参数说明
配置 | 缺省值 | 说明 |
name |
| 配置这个属性的意义在于,如果存在多个数据源,监控的时候可以通过名字来区分开来。 |
jdbcUrl |
| 连接数据库的url,不同数据库不一样。例如: |
username |
| 连接数据库的用户名 |
password |
| 连接数据库的密码。如果你不希望密码直接写在配置文件中,可以使用ConfigFilter。详细看这里:https://github.com/alibaba/druid/wiki/%E4%BD%BF%E7%94%A8ConfigFilter |
driverClassName | 根据url自动识别 | 这一项可配可不配,如果不配置druid会根据url自动识别dbType,然后选择相应的driverClassName(建议配置下) |
initialSize | 0 | 初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时 |
maxActive | 8 | 最大连接池数量 |
maxIdle | 8 | 已经不再使用,配置了也没效果 |
minIdle |
| 最小连接池数量 |
maxWait |
| 获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。 |
poolPreparedStatements | false | 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。 |
maxOpenPreparedStatements | -1 | 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100 |
validationQuery |
| 用来检测连接是否有效的sql,要求是一个查询语句。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会其作用。 |
testOnBorrow | true | 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 |
testOnReturn | false | 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能 |
testWhileIdle | false | 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 |
timeBetweenEvictionRunsMillis |
| 有两个含义: |
numTestsPerEvictionRun |
| 不再使用,一个DruidDataSource只支持一个EvictionRun |
minEvictableIdleTimeMillis |
|
|
connectionInitSqls |
| 物理连接初始化的时候执行的sql |
exceptionSorter | 根据dbType自动识别 | 当数据库抛出一些不可恢复的异常时,抛弃连接 |
filters |
| 属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有: |
proxyFilters |
| 类型是List<com.alibaba.druid.filter.Filter>,如果同时配置了filters和proxyFilters,是组合关系,并非替换关系 |
- spring-db.xml配置文件
<!-- 配置druid数据源 -->
<bean name="pooledDataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<!-- 数据库连接基础信息 -->
<property name="url" value="jdbc:mysql://localhost:3306/数据库名称?useUnicode=true&useSSL=false&characterEncoding=utf8" />
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="username" value="账号" />
<property name="password" value="密码" />
<!-- 初始化连接大小 -->
<property name="initialSize" value="0" />
<!-- 连接池最大使用连接数量 -->
<property name="maxActive" value="1500" />
<!-- 连接池最小空闲 -->
<property name="minIdle" value="0" />
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="60000" />
<!-- 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。 -->
<!--<property name="poolPreparedStatements" value="true" /> <property-->
<!--name="maxPoolPreparedStatementPerConnectionSize" value="33" /> -->
<!-- 验证数据库连接有效性,要求查询语句 -->
<property name="validationQuery" value="${validationQuery}" />
<!-- 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 -->
<property name="testWhileIdle" value="true" />
<!-- 申请连接时执行validationQuery检测连接是否有效,配置true会降低性能。 -->
<property name="testOnBorrow" value="false" />
<!-- 归还连接时执行validationQuery检测连接是否有效,配置true会降低性能 -->
<property name="testOnReturn" value="false" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="25200000" />
<!-- 对于长时间不使用的连接强制关闭 -->
<property name="removeAbandoned" value="true" />
<!-- 关闭超过30分钟的空闲连接,1800秒,也就是30分钟 -->
<property name="removeAbandonedTimeout" value="1800" />
<!-- 关闭abanded连接时输出错误日志 -->
<property name="logAbandoned" value="true" />
<!-- 监控数据库 -->
<property name="filters" value="start" />
</bean>
- web.xml
<!-- druid 监控 -->
<filter>
<filter-name>druidWebStatFilter</filter-name>
<filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>
<init-param>
<param-name>exclusions</param-name>
<param-value>/assets/*,*.css,*.js,*.gif,*.jpg,*.png,*.ico,*.eot,*.svg,*.ttf,*.woff,*.jsp,*.tpl,/druid/*</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>druidWebStatFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置 Druid 监控信息显示页面 -->
<servlet>
<servlet-name>DruidStatView</servlet-name>
<servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
<init-param>
<!-- 允许清空统计数据 -->
<param-name>resetEnable</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<!-- 用户名 -->
<param-name>loginUsername</param-name>
<param-value>admin</param-value>
</init-param>
<init-param>
<!-- 密码 -->
<param-name>loginPassword</param-name>
<param-value>admin</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DruidStatView</servlet-name>
<url-pattern>/druid/*</url-pattern>
</servlet-mapping>
只需要在启动spring窗口时候把加载数据操作换成加载spring-db.xml配置文件内容即可。
启动后在页面输入localhost:8080/druid
druid监控页面
SpringBoot
- 加入maven依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
- yum文件配置
spring:
datasource:
# 数据源基本配置
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_crud
type: com.alibaba.druid.pool.DruidDataSource
# 数据源其他配置
druid:
# 配置初始化大小、最小、最大线程数
initialSize: 5
minIdle: 5
# CPU核数+1,也可以大些但不要超过20,数据库加锁时连接过多性能下降
maxActive: 20
# 最大等待时间,内网:800,外网:1200(三次握手1s)
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最大空间时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1
testWhileIdle: true
# 设置从连接池获取连接时是否检查连接有效性,true检查,false不检查
testOnBorrow: true
# 设置从连接池归还连接时是否检查连接有效性,true检查,false不检查
testOnReturn: true
# 可以支持PSCache(提升写入、查询效率)
poolPreparedStatements: true
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,wall,log4j
# 保持长连接
keepAlive: true
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
- 添加配置类
@Configuration
public class DruidConfig{
@ConfigurationProperties(prefix='spring.datasource')
@Bean
public DateSource druid(){
return new DruidDataSource();
}
//配置Druid监控
@Bean
public ServletRegistrationBean statViewServlet(){
ServletRegistrationBean bean=new ServletRegistrationBean(new StatViewServlet(),"/druid/*");
Map<String,String> initParams=new HashMap<>();
initParams.put("loginUsername","admin");
initParams.put("loginPassword","admin");
initParams.put("allow","0.0.0.0");//默认允许所有访问
bean.setInitParameters(initParams);
return bean;
}
//配置一个web监控的filter
@Bean
public FilterRegistrationBean webStatFilter(){
FilterRegistrationBean bean=new FilterRegistrationBean();
bean.setFilter(new WebStatFilter());
Map<String,String> initParams=new HashMap<>();
initParams.put("exclusions","*.js,*.css,/druid/*");
bean.setInitParameters(initParams);
bean.setUrlPatterns(Arrays.asList("/*"));
return bean;
}
}
扩展配置
- spring监控
经过上述配置可以对sql进行监控,如果需要对spring容器进行监控需要改一下spring-db.xml配置文件(小编没有配置spring监控,发现可以对spring进行监控,有兴趣的小伙伴可以试一下)
上述完成后在spring-db.xml配置文件末添加
<!--配置druid监控spring jdbc -->
<bean id="druid-stat-interceptor"
class="com.alibaba.druid.support.spring.stat.DruidStatInterceptor" />
<bean id="druid-stat-pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut"
scope="prototype">
<property name="patterns">
<list>
<!--需要扫描代码的包-->
<value>com.springmvc.contorller.*</value>
<value>com.springmvc.service.*</value>
</list>
</property>
</bean>
<aop:config proxy-target-class="true">
<aop:advisor advice-ref="druid-stat-interceptor"
pointcut-ref="druid-stat-pointcut" />
</aop:config>
- druid密码加密
durid还有一个功能是密码加密。普通连接池是需要把密码以明文方式写入配置文件中,别人可以直接获得数据账号和密码等重要信息,通过druid加密后就可以避免这个问题。
可以参考表格password加密提示进行操作。
引入druid依赖程序会下载druid的Jar包,我们需要找到maven仓库中Jar包下载位置,在空白处按shift并右击选择用命令窗口打开
执行
java -cp druid-1.1.13.jar com.alibaba.druid.filter.config.ConfigTools 数据库密码
会生成公钥、私钥和密码,我们需要公钥和密码进行配置
修改spring-db.xml配置文件
<!-- filters的value属性start添加一个confg -->
<property name="filters" value="start,config" />
<!-- 添加公钥 -->
<property name="connectionProperties" value="config.decrypt=true;config.decrypt.key=${jdbc.publicKey}"/>