Spring Boot集成Druid實(shí)現(xiàn)數(shù)據(jù)源管理與監(jiān)控的詳細(xì)步驟
1. 引言
在程序員的日常工作中, 經(jīng)常需要編寫數(shù)據(jù)庫操作相關(guān)的程序,而這就需要數(shù)據(jù)連接池中間件用于管理數(shù)據(jù)庫連接。數(shù)據(jù)庫連接池負(fù)責(zé)分配、管理和釋放數(shù)據(jù)庫連接,它允許應(yīng)用程序重復(fù)使用一個(gè)現(xiàn)有的數(shù)據(jù)庫連接,而不是再重新建立一個(gè);釋放空閑時(shí)間超過最大空閑時(shí)間的數(shù)據(jù)庫連接來避免因?yàn)闆]有釋放數(shù)據(jù)庫連接而引起的數(shù)據(jù)庫連接遺漏。通過數(shù)據(jù)庫連接池能明顯提高對(duì)數(shù)據(jù)庫操作的性能。在Java應(yīng)用程序開發(fā)中,常用的連接池有DBCP、C3P0、Proxool等。
而在Spring Boot開發(fā)框架下,它默認(rèn)提供了若干種可用的連接池,其中包括Druid連接池(來自于阿里系的一個(gè)開源連接池),除在連接池之外,Druid還提供了非常優(yōu)秀的數(shù)據(jù)庫監(jiān)控和擴(kuò)展功能。在此,根據(jù)項(xiàng)目實(shí)踐中的應(yīng)用,講解如何實(shí)現(xiàn)Spring Boot與Druid連接池的集成。
1.1 環(huán)境準(zhǔn)備
- JDK 1.8
- Spring Boot 2.0.0.RELEASE
- MySQL 5.7
- Druid 1.1.9
1.2 Druid介紹
Druid是阿里開源的一個(gè)JDBC應(yīng)用組件, 其包括三部分:
- DruidDriver 代理Driver,能夠提供基于Filter-Chain模式的插件體系。
- DruidDataSource 高效可管理的數(shù)據(jù)庫連接池。
- SQLParser SQL語法分析
通過Druid連接池中間件, 我們可以實(shí)現(xiàn):
- 可以監(jiān)控?cái)?shù)據(jù)庫訪問性能,Druid內(nèi)置提供了一個(gè)功能強(qiáng)大的StatFilter插件,能夠詳細(xì)統(tǒng)計(jì)SQL的執(zhí)行性能,這對(duì)于線上分析數(shù)據(jù)庫訪問性能有幫助。
- 替換傳統(tǒng)的DBCP和C3P0連接池中間件。Druid提供了一個(gè)高效、功能強(qiáng)大、可擴(kuò)展性好的數(shù)據(jù)庫連接池。
- 數(shù)據(jù)庫密碼加密。直接把數(shù)據(jù)庫密碼寫在配置文件中,這是不好的行為,容易導(dǎo)致安全問題。DruidDruiver和DruidDataSource都支持PasswordCallback。
- SQL執(zhí)行日志,Druid提供了不同的LogFilter,能夠支持Common-Logging、Log4j和JdkLog,你可以按需要選擇相應(yīng)的LogFilter,監(jiān)控你應(yīng)用的數(shù)據(jù)庫訪問情況。
- 擴(kuò)展JDBC,如果你要對(duì)JDBC層有編程的需求,可以通過Druid提供的Filter-Chain機(jī)制,很方便編寫JDBC層的擴(kuò)展插件。
關(guān)于Druid的更多詳細(xì)信息可以參考Druid官方文檔
2. 配置Druid連接池
(1) 添加Maven依賴
<dependencies>
... 此處省略其他配置 ...
<!-- Configuration Module -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- MySQL Driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.45</version>
<scope>runtime</scope>
</dependency>
<!-- Druid Pool -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.9</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency>
</dependencies>(2) Spring Boot配置文件配置
Spring Boot配置文件有application.properties和application.yml兩種配置文件方式 , 此處采用的是application.yml的配置方式。
# Spring Datasource Settings
spring:
datasource:
name: druidDataSource
type: com.alibaba.druid.pool.DruidDataSource
druid:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.202.17:3306/auth_service?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false
username: root
password: 123456
filters: stat,wall,log4j,config
max-active: 100
initial-size: 1
max-wait: 60000
min-idle: 1
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: select 'x'
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: true
max-open-prepared-statements: 50
max-pool-prepared-statement-per-connection-size: 20說明:
- spring.datasource.druid.max-active 最大連接數(shù)
- spring.datasource.druid.initial-size 初始化大小
- spring.datasource.druid.min-idle 最小連接數(shù)
- spring.datasource.druid.max-wait 獲取連接等待超時(shí)時(shí)間
- spring.datasource.druid.time-between-eviction-runs-millis 間隔多久才進(jìn)行一次檢測,檢測需要關(guān)閉的空閑連接,單位是毫秒
- spring.datasource.druid.min-evictable-idle-time-millis 一個(gè)連接在池中最小生存的時(shí)間,單位是毫秒
- spring.datasource.druid.filters=config,stat,wall,log4j 配置監(jiān)控統(tǒng)計(jì)攔截的filters,去掉后監(jiān)控界面SQL無法進(jìn)行統(tǒng)計(jì),’wall’用于防火墻
Druid提供以下幾種Filter信息:
| Filter類名 | 別名 |
|---|---|
| default | com.alibaba.druid.filter.stat.StatFilter |
| stat | com.alibaba.druid.filter.stat.StatFilter |
| mergeStat | com.alibaba.druid.filter.stat.MergeStatFilter |
| encoding | com.alibaba.druid.filter.encoding.EncodingConvertFilter |
| log4j | com.alibaba.druid.filter.logging.Log4jFilter |
| log4j2 | com.alibaba.druid.filter.logging.Log4j2Filter |
| slf4j | com.alibaba.druid.filter.logging.Slf4jLogFilter |
| commonlogging | com.alibaba.druid.filter.logging.CommonsLogFilter |
| wall | com.alibaba.druid.wall.WallFilter |
(3) Druid配置信息定制
通過Druid-Spring-Boot-Starter可以自動(dòng)完成相關(guān)的配置, 而無須自定義配置文件, 具體參考Druid-Spring-Boot-Starter。
通過Druid-Spring-Boot-Starter的Spring Boot配置信息示例:
spring:
datasource:
name: druidDataSource
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.202.17:3306/auth_service?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false
username: root
password: 123456
druid:
filters: stat,wall,log4j,config
max-active: 100
initial-size: 1
max-wait: 60000
min-idle: 1
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: select 'x'
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: true
max-open-prepared-statements: 50
max-pool-prepared-statement-per-connection-size: 20在此, 主要通過定制的配置文件對(duì)Druid進(jìn)行自定義屬性配置, 配置文件如下:
package com.garyond.hurricane.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "spring.datasource.druid")
public class DruidDataSourceProperties {
private String driverClassName;
private String url;
private String username;
private String password;
private int initialSize;
private int minIdle;
private int maxActive = 100;
private long maxWait;
private long timeBetweenEvictionRunsMillis;
private long minEvictableIdleTimeMillis;
private String validationQuery;
private boolean testWhileIdle;
private boolean testOnBorrow;
private boolean testOnReturn;
private boolean poolPreparedStatements;
private int maxPoolPreparedStatementPerConnectionSize;
private String filters;
public int getInitialSize() {
return initialSize;
}
public void setInitialSize(int initialSize) {
this.initialSize = initialSize;
}
public int getMinIdle() {
return minIdle;
}
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
public int getMaxActive() {
return maxActive;
}
public void setMaxActive(int maxActive) {
this.maxActive = maxActive;
}
public long getMaxWait() {
return maxWait;
}
public void setMaxWait(long maxWait) {
this.maxWait = maxWait;
}
public long getTimeBetweenEvictionRunsMillis() {
return timeBetweenEvictionRunsMillis;
}
public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
}
public long getMinEvictableIdleTimeMillis() {
return minEvictableIdleTimeMillis;
}
public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
}
public String getValidationQuery() {
return validationQuery;
}
public void setValidationQuery(String validationQuery) {
this.validationQuery = validationQuery;
}
public boolean isTestWhileIdle() {
return testWhileIdle;
}
public void setTestWhileIdle(boolean testWhileIdle) {
this.testWhileIdle = testWhileIdle;
}
public boolean isTestOnBorrow() {
return testOnBorrow;
}
public void setTestOnBorrow(boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
}
public boolean isTestOnReturn() {
return testOnReturn;
}
public void setTestOnReturn(boolean testOnReturn) {
this.testOnReturn = testOnReturn;
}
public boolean isPoolPreparedStatements() {
return poolPreparedStatements;
}
public void setPoolPreparedStatements(boolean poolPreparedStatements) {
this.poolPreparedStatements = poolPreparedStatements;
}
public int getMaxPoolPreparedStatementPerConnectionSize() {
return maxPoolPreparedStatementPerConnectionSize;
}
public void setMaxPoolPreparedStatementPerConnectionSize(int maxPoolPreparedStatementPerConnectionSize) {
this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize;
}
public String getFilters() {
return filters;
}
public void setFilters(String filters) {
this.filters = filters;
}
public String getDriverClassName() {
return driverClassName;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}(3) 配置Druid相關(guān)的Servlet和Filter
package com.garyond.hurricane.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.sql.SQLException;
@Configuration
@EnableConfigurationProperties({DruidDataSourceProperties.class})
public class DruidConfig {
@Autowired
private DruidDataSourceProperties properties;
@Bean
@ConditionalOnMissingBean
public DataSource druidDataSource() {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(properties.getDriverClassName());
druidDataSource.setUrl(properties.getUrl());
druidDataSource.setUsername(properties.getUsername());
druidDataSource.setPassword(properties.getPassword());
druidDataSource.setInitialSize(properties.getInitialSize());
druidDataSource.setMinIdle(properties.getMinIdle());
druidDataSource.setMaxActive(properties.getMaxActive());
druidDataSource.setMaxWait(properties.getMaxWait());
druidDataSource.setTimeBetweenEvictionRunsMillis(properties.getTimeBetweenEvictionRunsMillis());
druidDataSource.setMinEvictableIdleTimeMillis(properties.getMinEvictableIdleTimeMillis());
druidDataSource.setValidationQuery(properties.getValidationQuery());
druidDataSource.setTestWhileIdle(properties.isTestWhileIdle());
druidDataSource.setTestOnBorrow(properties.isTestOnBorrow());
druidDataSource.setTestOnReturn(properties.isTestOnReturn());
druidDataSource.setPoolPreparedStatements(properties.isPoolPreparedStatements());
druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(properties.getMaxPoolPreparedStatementPerConnectionSize());
try {
druidDataSource.setFilters(properties.getFilters());
druidDataSource.init();
} catch (SQLException e) {
e.printStackTrace();
}
return druidDataSource;
}
/**
* 注冊(cè)Servlet信息, 配置監(jiān)控視圖
*
* @return
*/
@Bean
@ConditionalOnMissingBean
public ServletRegistrationBean druidServlet() {
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
//白名單:
servletRegistrationBean.addInitParameter("allow","192.168.6.195");
//IP黑名單 (存在共同時(shí),deny優(yōu)先于allow) : 如果滿足deny的話提示:Sorry, you are not permitted to view this page.
servletRegistrationBean.addInitParameter("deny","192.168.6.73");
//登錄查看信息的賬號(hào)密碼, 用于登錄Druid監(jiān)控后臺(tái)
servletRegistrationBean.addInitParameter("loginUsername", "admin");
servletRegistrationBean.addInitParameter("loginPassword", "admin");
//是否能夠重置數(shù)據(jù).
servletRegistrationBean.addInitParameter("resetEnable", "true");
return servletRegistrationBean;
}
/**
* 注冊(cè)Filter信息, 監(jiān)控?cái)r截器
*
* @return
*/
@Bean
@ConditionalOnMissingBean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new WebStatFilter());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
return filterRegistrationBean;
}
}注:
- @EnableConfigurationProperties({DruidDataSourceProperties.class}) 用于導(dǎo)入上一步Druid的配置信息
- public ServletRegistrationBean druidServlet() 相當(dāng)于Web Servlet配置
- public FilterRegistrationBean filterRegistrationBean() 相當(dāng)于Web Filter配置
如果不使用上述的Servlet和Filter配置, 也可以通過下述監(jiān)控器配置實(shí)現(xiàn):
配置監(jiān)控?cái)r截器(相當(dāng)于FilterRegistrationBean)
/**
* 配置監(jiān)控?cái)r截器, druid監(jiān)控?cái)r截器
* @ClassName: DruidStatFilter
* @author garyond
* @date 2018年4月24日
*/
@WebFilter(filterName="druidWebStatFilter",
urlPatterns="/*",
initParams={
@WebInitParam(name="exclusions",value="*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"),// 忽略資源
})
public class DruidStatFilter extends WebStatFilter {
} 配置Druid監(jiān)控視圖(相當(dāng)于ServletRegistrationBean)
/**
* druid監(jiān)控視圖配置
*
* @ClassName: DruidStatViewServlet
* @author garyond
* @date 2018年4月24日
*/
@WebServlet(urlPatterns = "/druid/*", initParams={
@WebInitParam(name="allow",value="192.168.6.195"),// IP白名單 (沒有配置或者為空,則允許所有訪問)
@WebInitParam(name="deny",value="192.168.6.73"),// IP黑名單 (存在共同時(shí),deny優(yōu)先于allow)
@WebInitParam(name="loginUsername",value="admin"),// 用戶名
@WebInitParam(name="loginPassword",value="admin"),// 密碼
@WebInitParam(name="resetEnable",value="true")// 禁用HTML頁面上的“Reset All”功能
})
public class DruidStatViewServlet extends StatViewServlet {
private static final long serialVersionUID = 7359758657306626394L;
} 3. 查看Druid監(jiān)控
配置完成后, 并完成相關(guān)的數(shù)據(jù)庫操作配置, 啟動(dòng)Spring Boot應(yīng)用程序,就可以通過訪問: http://localhost:8080/druid/index.html 訪問Druid監(jiān)控后臺(tái)頁面。

輸入用戶名和密碼可以查看Druid監(jiān)控信息:


至此, Spring Boot集成Druid連接池已配置完畢。
到此這篇關(guān)于Spring Boot集成Druid實(shí)現(xiàn)數(shù)據(jù)源管理與監(jiān)控的詳細(xì)步驟的文章就介紹到這了,更多相關(guān)Spring Boot Druid數(shù)據(jù)源管理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot中Druid連接池與多數(shù)據(jù)源切換的方法
- SpringBoot集成Druid實(shí)現(xiàn)多數(shù)據(jù)源的兩種方式
- SpringBoot整合Mybatis-Plus+Druid實(shí)現(xiàn)多數(shù)據(jù)源配置功能
- SpringBoot使用druid配置多數(shù)據(jù)源問題
- springboot mybatis druid配置多數(shù)據(jù)源教程
- 關(guān)于springboot配置druid數(shù)據(jù)源不生效問題(踩坑記)
- 使用springboot+druid雙數(shù)據(jù)源動(dòng)態(tài)配置操作
相關(guān)文章
第三方網(wǎng)站微信登錄java代碼實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了第三方網(wǎng)站微信登錄的java代碼實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04
SpringCloud Gateway 利用 Mysql 實(shí)現(xiàn)動(dòng)態(tài)路由的方法
這篇文章主要介紹了SpringCloud Gateway 利用 Mysql 實(shí)現(xiàn)動(dòng)態(tài)路由的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02
使用Java實(shí)現(xiàn)文件大小過濾功能(附源碼)
在實(shí)際開發(fā)中,經(jīng)常需要對(duì)大量文件進(jìn)行批量處理,對(duì)于這些場景,開發(fā)者往往需要根據(jù)文件的大小進(jìn)行篩選,本文就來利用Java實(shí)現(xiàn)文件大小過濾功能,有需要的可以了解下2025-06-06
解決SpringBoot整合MybatisPlus分模塊管理遇到的bug
這篇文章主要介紹了解決SpringBoot整合MybatisPlus分模塊管理遇到的bug,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
SpringMVC中常用參數(shù)校驗(yàn)類注解使用示例教程
這篇文章主要介紹了SpringMVC中常用參數(shù)校驗(yàn)類注解使用示例教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-03-03

