專案已托管於 GitHub:y0ngb1n/spring-boot-samples,歡迎 Star, Fork 😘
添加依賴 #
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${alibaba-druid.version}</version>
</dependency>
配置屬性#
spring:
datasource:
url: jdbc:h2:mem:recommend
username: sa
password:
##
# 設置資料源類型為 DruidDataSource
##
type: com.alibaba.druid.pool.DruidDataSource
druid:
##
# 配置初始化大小、最小、最大連接池數量
# - min-idle:池中維護的最小空閒連接數,默認為 0 個
# - max-active:池中最大連接數,包括閒置和使用中的連接,默認為 8 個;推薦配置:20,多數場景下 20 已完全夠用,當然這個參數跟使用場景相關性很大,一般配置成正常連接數的 3~5 倍。
##
initial-size: 5
min-idle: 10
max-active: 20
##
# 參數表示是否對空閒連接保活,布林類型。
#
# 那麼需要保活連接,是不是將 keepAlive 配置成 true 就完事了呢?
# 雖然 true 的確是開啟了保活機制,但是應該保活多少個,心跳檢查的規則是什麼,這些都需要正確配置,否則還是可能事與願違。
# 這裡需要了解幾個相關的參數:minIdle 最小連接池數量,連接保活的數量,空閒連接超時踢除過程會保留的連接數(前提是當前連接數大於等於 minIdle),其實 keepAlive 也僅維護已存在的連接,而不會去新建連接,即使連接數小於 minIdle;
# minEvictableIdleTimeMillis 單位毫秒,連接保持空閒而不被驅逐的最小時間,保活心跳只對存活時間超過這個值的連接進行;
# maxEvictableIdleTimeMillis 單位毫秒,連接保持空閒的最長時間,如果連接執行過任何操作後計時器就會被重置(包括心跳保活動作);
# timeBetweenEvictionRunsMillis 單位毫秒,Destroy 線程檢測連接的間隔時間,會在檢測過程中觸發心跳。保活檢查的詳細流程可參見源碼 com.alibaba.druid.pool.DruidDataSource.DestroyTask,其中心跳檢查會根據配置使用 ping 或 validationQuery 配置的檢查語句。
#
# 推薦配置:如果網路狀況不佳,程式啟動慢或者經常出現突發流量,則推薦配置為 true;
##
keep-alive: true
# 配置一個連接在池中最小生存的時間,單位是毫秒
min-evictable-idle-time-millis: 600000
max-evictable-idle-time-millis: 900000
# 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連接,單位是毫秒
time-between-eviction-runs-millis: 2000
##
# 配置獲取連接等待超時的時間
#
# 推薦配置:
# - 內網(網路狀況好)800;
# - 網路狀況不是特別好的情況下推薦大於等於 1200,因為 tcp 建連重試一般是 1 秒;
##
max-wait: 800
##
# 可以配置 connectTimeout 和 socketTimeout,它們的單位都是毫秒,這兩個參數在應對網路異常方面非常重要。
# - connectTimeout 配置建立 TCP 連接的超時時間;
# - socketTimeout 配置發送請求後等待響應的超時時間;
# 這兩個參數也可以通過在 jdbc url 中添加 connectTimeout=xxx&socketTimeout=xxx 的方式配置,試過在 connectinoProperties 中和 jdbc url兩個地方都配置,發現優先使用 connectionProperties 中的配置。
# 如果不設置這兩項超時時間,服務會有非常高的風險。現實案例是在網路異常後發現應用無法連接到 DB,但是重啟後卻能正常的訪問 DB。因為在網路異常下 socket 沒有辦法檢測到網路錯誤,這時連接其實已經變為“死連接”,如果沒有設置 socket 網路超時,連接就會一直等待 DB 返回結果,造成新的請求都無法獲取到連接。
#
# 推薦配置:socketTimeout=3000;connectTimeout=1200
##
connect-properties: socketTimeout=3000;connectTimeout=1200
##
# 用於檢測連接是否有效的 SQL 語句
##
validation-query: select 1
##
# 申請連接的時候檢測,如果空閒時間大於 timeBetweenEvictionRunsMillis,執行 validationQuery 檢測連接是否有效
##
test-while-idle: true
##
# 申請連接時執行 validationQuery 檢測連接是否有效,做了這個配置會降低性能
##
test-on-borrow: false
##
# 归还连接时执行 validationQuery 检测连接是否有效,做了这个配置会降低性能
##
test-on-return: false
##
# 通过限制达到一定使用次数后断开重连,使得多个服务器间负载更均衡
##
phy-max-use-count: 1000
多資料源#
添加配置#
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
##
# 合併多個 DruidDataSource 的監控數據
##
use-global-data-source-stat: true
##
# Druid 資料源 1 配置
##
foo:
url: jdbc:h2:mem:foo
username: foo
password:
initial-size: 5
min-idle: 10
max-active: 20
maxWait: 800
##
# Druid 資料源 2 配置
##
bar:
url: jdbc:h2:mem:bar
username: bar
password:
initial-size: 5
min-idle: 10
max-active: 20
maxWait: 1200
創建資料源#
@Configuration
public class DruidConfig {
@Bean
@Primary
@ConfigurationProperties("spring.datasource.druid.foo")
public DataSource dataSourceFoo() {
return DruidDataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties("spring.datasource.druid.bar")
public DataSource dataSourceBar() {
return DruidDataSourceBuilder.create().build();
}
}
配置 Filter#
spring:
datasource:
druid:
filters: config,stat,slf4j
filter:
config:
enabled: true
##
# 配置 StatFilter,參考文檔:https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_StatFilter
##
stat:
enabled: true
# 開啟慢查詢記錄
log-slow-sql: true
# 慢 SQL 的標準,單位:毫秒
slow-sql-millis: 5000
slf4j:
enabled: true
wall:
enabled: true
##
# 配置 StatViewServlet,參考文檔:https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_StatViewServlet%E9%85%8D%E7%BD%AE
# 訪問 http://127.0.0.1:8080/druid 地址,可以看到監控頁面
##
stat-view-servlet:
enabled: true
login-username: yangbin
login-password: yangbin
監控數據#
@RestController
public class DruidStatController {
@GetMapping("/druid/stat")
public Object druidStat() {
return DruidStatManagerFacade.getInstance().getDataSourceStatDataList();
}
}