y0ngb1n

Aben Blog

欢迎来到我的技术小黑屋ヾ(◍°∇°◍)ノ゙
github

最佳實踐丨快速集成 Alibaba Druid 資料庫連接池

專案已托管於 GitHub:y0ngb1n/spring-boot-samples,歡迎 Star, Fork 😘


添加依賴 Maven Central#

<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();
  }
}

🔗️ 參考鏈接#

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。