上一節,咱們介紹了Spring Boot在JDBC模塊中自動化配置使用的默認數據源HikariCP。接下來這一節,咱們將介紹另一個被普遍應用的開源數據源:Druid。mysql
Druid是由阿里巴巴數據庫事業部出品的開源項目。它除了是一個高性能數據庫鏈接池以外,更是一個自帶監控的數據庫鏈接池。雖然HikariCP已經很優秀,可是對於國內用戶來講,可能對於Druid更爲熟悉。因此,對於如何在Spring Boot中使用Druid是後端開發人員必需要掌握的基本技能。git
這一節的實踐咱們將基於《Spring Boot 2.x基礎教程:使用JdbcTemplate訪問MySQL數據庫》一文的代碼基礎上進行。因此,讀者能夠從文末的代碼倉庫中,檢出chapter3-1
目錄來進行下面的實踐學習。github
下面咱們就來開始對Spring Boot項目配置Druid數據源:spring
第一步:在pom.xml
中引入druid官方提供的Spring Boot Starter封裝。sql
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.21</version>
</dependency>
複製代碼
第二步:在application.properties
中配置數據庫鏈接信息。數據庫
Druid的配置都以spring.datasource.druid
做爲前綴,因此根據以前的配置,稍做修改便可:後端
spring.datasource.druid.url=jdbc:mysql://localhost:3306/test
spring.datasource.druid.username=root
spring.datasource.druid.password=
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
複製代碼
第三步:配置Druid的鏈接池。緩存
與Hikari同樣,要用好一個數據源,就要對其鏈接池作好相應的配置,好比下面這樣:安全
spring.datasource.druid.initialSize=10
spring.datasource.druid.maxActive=20
spring.datasource.druid.maxWait=60000
spring.datasource.druid.minIdle=1
spring.datasource.druid.timeBetweenEvictionRunsMillis=60000
spring.datasource.druid.minEvictableIdleTimeMillis=300000
spring.datasource.druid.testWhileIdle=true
spring.datasource.druid.testOnBorrow=true
spring.datasource.druid.testOnReturn=false
spring.datasource.druid.poolPreparedStatements=true
spring.datasource.druid.maxOpenPreparedStatements=20
spring.datasource.druid.validationQuery=SELECT 1
spring.datasource.druid.validation-query-timeout=500
spring.datasource.druid.filters=stat
複製代碼
關於Druid中各鏈接池配置的說明可查閱下面的表格:bash
配置 | 缺省值 | 說明 |
---|---|---|
name | 配置這個屬性的意義在於,若是存在多個數據源,監控的時候能夠經過名字來區分開來。若是沒有配置,將會生成一個名字,格式是:」DataSource-「 + System.identityHashCode(this). 另外配置此屬性至少在1.0.5版本中是不起做用的,強行設置name會出錯。詳情-點此處。 | |
url | 鏈接數據庫的url,不一樣數據庫不同。例如: mysql : jdbc:mysql://10.20.153.104:3306/druid2 oracle : jdbc:oracle:thin:@10.20.149.85:1521:ocnauto | |
username | 鏈接數據庫的用戶名 | |
password | 鏈接數據庫的密碼。若是你不但願密碼直接寫在配置文件中,可使用ConfigFilter。詳細看這裏 | |
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下建議關閉。 |
maxPoolPreparedStatementPerConnectionSize | -1 | 要啓用PSCache,必須配置大於0,當大於0時,poolPreparedStatements自動觸發修改成true。在Druid中,不會存在Oracle下PSCache佔用內存過多的問題,能夠把這個數值配置大一些,好比說100 |
validationQuery | 用來檢測鏈接是否有效的sql,要求是一個查詢語句,經常使用select ‘x’。若是validationQuery爲null,testOnBorrow、testOnReturn、testWhileIdle都不會起做用。 | |
validationQueryTimeout | 單位:秒,檢測鏈接是否有效的超時時間。底層調用jdbc Statement對象的void setQueryTimeout(int seconds)方法 | |
testOnBorrow | true | 申請鏈接時執行validationQuery檢測鏈接是否有效,作了這個配置會下降性能。 |
testOnReturn | false | 歸還鏈接時執行validationQuery檢測鏈接是否有效,作了這個配置會下降性能。 |
testWhileIdle | false | 建議配置爲true,不影響性能,而且保證安全性。申請鏈接的時候檢測,若是空閒時間大於timeBetweenEvictionRunsMillis,執行validationQuery檢測鏈接是否有效。 |
keepAlive | false (1.0.28) | 鏈接池中的minIdle數量之內的鏈接,空閒時間超過minEvictableIdleTimeMillis,則會執行keepAlive操做。 |
timeBetweenEvictionRunsMillis | 1分鐘(1.0.14) | 有兩個含義: 1) Destroy線程會檢測鏈接的間隔時間,若是鏈接空閒時間大於等於minEvictableIdleTimeMillis則關閉物理鏈接。 2) testWhileIdle的判斷依據,詳細看testWhileIdle屬性的說明 |
numTestsPerEvictionRun | 30分鐘(1.0.14) | 再也不使用,一個DruidDataSource只支持一個EvictionRun |
minEvictableIdleTimeMillis | 鏈接保持空閒而不被驅逐的最小時間 | |
connectionInitSqls | 物理鏈接初始化的時候執行的sql | |
exceptionSorter | 根據dbType自動識別 | 當數據庫拋出一些不可恢復的異常時,拋棄鏈接 |
filters | 屬性類型是字符串,經過別名的方式配置擴展插件,經常使用的插件有: 監控統計用的filter:stat 日誌用的filter:log4j 防護sql注入的filter:wall | |
proxyFilters | 類型是List<com.alibaba.druid.filter.Filter>,若是同時配置了filters和proxyFilters,是組合關係,並不是替換關係 |
到這一步,就已經完成了將Spring Boot的默認數據源HikariCP切換到Druid的全部操做。
既然用了Druid,那麼對於Druid的監控功能怎麼能不用一下呢?下面就來再進一步作一些配置,來啓用Druid的監控。
第一步:在pom.xml
中引入spring-boot-starter-actuator
模塊
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
複製代碼
第二步:在application.properties
中添加Druid的監控配置。
spring.datasource.druid.stat-view-servlet.enabled=true
spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
spring.datasource.druid.stat-view-servlet.reset-enable=true
spring.datasource.druid.stat-view-servlet.login-username=admin
spring.datasource.druid.stat-view-servlet.login-password=admin
複製代碼
上面的配置主要用於開啓stat監控統計的界面以及監控內容的相關配置,具體釋意以下:
spring.datasource.druid.stat-view-servlet.url-pattern
:訪問地址規則spring.datasource.druid.stat-view-servlet.reset-enable
:是否容許清空統計數據spring.datasource.druid.stat-view-servlet.login-username
:監控頁面的登陸帳戶spring.datasource.druid.stat-view-servlet.login-password
:監控頁面的登陸密碼第三步:針對以前實現的UserService
內容,咱們建立一個Controller來經過接口去調用數據訪問操做:
@Data
@AllArgsConstructor
@RestController
public class UserController {
private UserService userService;
@PostMapping("/user")
public int create(@RequestBody User user) {
return userService.create(user.getName(), user.getAge());
}
@GetMapping("/user/{name}")
public List<User> getByName(@PathVariable String name) {
return userService.getByName(name);
}
@DeleteMapping("/user/{name}")
public int deleteByName(@PathVariable String name) {
return userService.deleteByName(name);
}
@GetMapping("/user/count")
public int getAllUsers() {
return userService.getAllUsers();
}
@DeleteMapping("/user/all")
public int deleteAllUsers() {
return userService.deleteAllUsers();
}
}
複製代碼
第四步:完成上面全部配置以後,啓動應用,訪問Druid的監控頁面http://localhost:8080/druid/
,能夠看到以下登陸頁面:
輸入上面spring.datasource.druid.stat-view-servlet.login-username
和spring.datasource.druid.stat-view-servlet.login-password
配置的登陸帳戶與密碼,就能看到以下監控頁面:
進入到這邊時候,就能夠看到對於應用端而言的各類監控數據了。這裏講解幾個最爲經常使用的監控頁面:
數據源:這裏能夠看到以前咱們配置的數據庫鏈接池信息以及當前使用狀況的各類指標。
SQL監控:該數據源中執行的SQL語句極其統計數據。在這個頁面上,咱們能夠很方便的看到當前這個Spring Boot都執行過哪些SQL,這些SQL的執行頻率和執行效率也均可以清晰的看到。若是你這裏沒看到什麼數據?別忘了咱們以前建立了一個Controller,用這些接口能夠觸發UserService對數據庫的操做。因此,這裏咱們能夠經過調用接口的方式去觸發一些操做,這樣SQL監控頁面就會產生一些數據:
圖中監控項上,執行時間、讀取行數、更新行數都經過區間分佈的方式表示,將耗時分佈成8個區間:
記錄耗時區間的發生次數,經過區分分佈,能夠很方便看出SQL運行的極好、普通和極差的分佈。 耗時區分分佈提供了「執行+RS時分佈」,是將執行時間+ResultSet持有時間合併監控,這個能方便診斷返回行數過多的查詢。
SQL防火牆:該頁面記錄了與SQL監控不一樣維度的監控數據,更多用於對錶訪問維度、SQL防護維度的統計。
該功能數據記錄的統計須要在spring.datasource.druid.filters
中增長wall
屬性纔會進行記錄統計,好比這樣:
spring.datasource.druid.filters=stat,wall
複製代碼
注意:這裏的全部監控信息是對這個應用實例的數據源而言的,而並非數據庫全局層面的,能夠視爲應用層的監控,不可能做爲中間件層的監控。
本文的相關例子能夠查看下面倉庫中的chapter3-3
目錄:
若是您以爲本文不錯,歡迎Star
支持,您的關注是我堅持的動力!
歡迎關注個人公衆號:程序猿DD,得到獨家整理的學習資源和平常乾貨推送。 若是您對個人專題內容感興趣,也能夠關注個人博客:didispace.com