ApiBoot DataSource Switch 使用文檔

ApiBoot是一款基於SpringBoot1.x,2.x的接口服務集成基礎框架, 內部提供了框架的封裝集成、使用擴展、自動化完成配置,讓接口開發者能夠選着性完成開箱即用, 再也不爲搭建接口框架而犯愁,從而極大的提升開發效率。java

ApiBoot DataSource Switch

顧名思義,DataSource Switch是用於數據源選擇切換的框架,這是一款基於Spring AOP切面指定註解實現的,經過簡單的數據源註解配置就能夠完成訪問時的自動切換,DataSource Switch切換過程當中是線程安全的。mysql

添加依賴

使用DataSource Switch很簡單,在pom.xml配置文件內添加以下依賴:git

<!--ApiBoot DataSource Switch-->
<dependency>
  <groupId>org.minbox.framework</groupId>
  <artifactId>api-boot-starter-datasource-switch</artifactId>
</dependency>
複製代碼

ApiBoot所提供的依賴都不須要添加版本號,具體查看ApiBoot版本依賴github

集成數據源實現

目前ApiBoot DataSource Switch集成了DruidHikariCP兩種數據源實現依賴,在使用方面也有必定的差別,由於每個數據源的內置參數不一致。sql

  • Druid:參數配置前綴爲api.boot.datasource.druid
  • HikariCP:參數配置前綴爲api.boot.datasource.hikari

具體使用請查看下面功能配置介紹。數據庫

配置參數

參數名 參數默認值 是否必填 參數描述
api.boot.datasource.primary master 主數據源名稱
api.boot.datasource.druid.{poolName}.url 數據庫鏈接字符串
api.boot.datasource.druid.{poolName}.username 用戶名
api.boot.datasource.druid.{poolName}.password 密碼
api.boot.datasource.druid.{poolName}.driver-class-name com.mysql.cj.jdbc.Driver 驅動類型
api.boot.datasource.druid.{poolName}.filters stat,wall,slf4j Druid過濾
api.boot.datasource.druid.{poolName}.max-active 20 最大鏈接數
api.boot.datasource.druid.{poolName}.initial-size 1 初始化鏈接數
api.boot.datasource.druid.{poolName}.max-wait 60000 最大等待市場,單位:毫秒
api.boot.datasource.druid.{poolName}.validation-query select 1 from dual 檢查sql
api.boot.datasource.druid.{poolName}.test-while-idle true 建議配置爲true,不影響性能,而且保證安全性。申請鏈接的時候檢測,若是空閒時間大於timeBetweenEvictionRunsMillis,執行validationQuery檢測鏈接是否有效。
api.boot.datasource.druid.{poolName}.test-on-borrow false 申請鏈接時執行validationQuery檢測鏈接是否有效,作了這個配置會下降性能。
api.boot.datasource.druid.{poolName}.test-on-return false 歸還鏈接時執行validationQuery檢測鏈接是否有效,作了這個配置會下降性能。
api.boot.datasource.hikari.{poolName}.url 數據庫鏈接字符串
api.boot.datasource.hikari.{poolName}.username 用戶名
api.boot.datasource.hikari.{poolName}.password 密碼
api.boot.datasource.hikari.{poolName}.driver-class-name com.mysql.cj.jdbc.Driver 數據庫驅動類全限定名
api.boot.datasource.hikari.{poolName}.property HikariCP屬性配置

HikariCP數據源是SpringBoot2.x自帶的,配置參數請訪問HikariCPapi

單主配置

ApiBoot DataSource Switch支持單主數據源的配置,application.yml配置文件以下所示:安全

api:
 boot:
 datasource:
      # 配置使用hikari數據源
 hikari:
        # master datasource config
 master:
 url: jdbc:mysql://localhost:3306/test?characterEncoding=utf8&serverTimezone=Asia/Shanghai
 username: root
 password: 123456
複製代碼

修改主數據源名稱

master爲默認的主數據源的poolName,這裏能夠進行修改成其餘值,不過須要對應修改primary參數,以下所示:多線程

api:
 boot:
 datasource:
      # 主數據源,默認值爲master
 primary: main
      # 配置使用hikari數據源
 hikari:
        # main datasource config
 main:
 url: jdbc:mysql://localhost:3306/test?characterEncoding=utf8&serverTimezone=Asia/Shanghai
 username: root
 password: 123456
複製代碼

在上面配置主數據源的poolName修改成mainoracle

主從配置

若是你的項目內存在單主單從一主多從的配置方式,以下所示:

api:
 boot:
 datasource:
      # 配置使用hikari數據源
 hikari:
        # master datasource config
 master:
 url: jdbc:mysql://localhost:3306/test?characterEncoding=utf8&serverTimezone=Asia/Shanghai
 username: root
 password: 123456
          # 默認值爲【com.mysql.cj.jdbc.Driver】
          #driver-class-name: com.mysql.cj.jdbc.Driver
        # slave 1 datasource config
 slave_1:
 url: jdbc:mysql://localhost:3306/oauth2?characterEncoding=utf8&serverTimezone=Asia/Shanghai
 username: root
 password: 123456
        # slave 2 datasource config
 slave_2:
 url: jdbc:mysql://localhost:3306/resources?characterEncoding=utf8&serverTimezone=Asia/Shanghai
 username: root
 password: 123456
複製代碼

在上面是一主多從的配置方式,分別是masterslave_1slave_2

多類型數據庫配置

ApiBoot DataSource Switch提供了一個項目內鏈接多個不一樣類型的數據庫,如:MySQLOracle...等,以下所示:

api:
 boot:
      # 主數據源,默認值爲master
 primary: mysql
 hikari:
 mysql:
 url: jdbc:mysql://localhost:3306/test?characterEncoding=utf8&serverTimezone=Asia/Shanghai
 username: root
 password: 123456
 oracle:
 url: jdbc:oracle:thin:@172.16.10.25:1521:torcl
 username: root
 password: 123456
 driver-class-name: oracle.jdbc.driver.OracleDriver
複製代碼

在上面配置中,master主數據源使用的MySQL驅動鏈接MySQL數據庫,而slave從數據源則是使用的Oracle驅動鏈接的Oracle數據庫。

動態建立數據源

ApiBoot DataSource Switch內部提供了動態建立數據源的方法,能夠經過注入ApiBootDataSourceFactoryBean來進行添加,以下所示:

@Autowired
private ApiBootDataSourceFactoryBean factoryBean;

public void createNewDataSource() throws Exception {
  // 建立Hikari數據源
  // 若是建立Druid數據源,使用DataSourceDruidConfig
  DataSourceHikariConfig config = new DataSourceHikariConfig();
  // 數據庫鏈接:必填
  config.setUrl("jdbc:mysql://localhost:3306/resources");
  // 用戶名:必填
  config.setUsername("root");
  // 密碼:必填
  config.setPassword("123456");
  // 數據源名稱:必填(用於@DataSourceSwitch註解value值使用)
  config.setPoolName("dynamic");

  // 建立數據源
  DataSource dataSource = factoryBean.newDataSource(config);
  Connection connection = dataSource.getConnection();
  System.out.println(connection.getCatalog());
  connection.close();
}
複製代碼

自動切換

ApiBoot DataSource Switch的數據源自動切換主要歸功於SpringAOP,經過切面@DataSourceSwitch註解,獲取註解配置的value值進行設置當前線程所用的數據源名稱,從而經過AbstractRoutingDataSource進行數據源的路由切換。

咱們沿用上面一主多從的配置進行代碼演示,配置文件application.yml參考上面配置,代碼示例以下:

從數據源示例類

@Service
@DataSourceSwitch("slave")
public class SlaveDataSourceSampleService {
    /** * DataSource Instance */
    @Autowired
    private DataSource dataSource;

    /** * 演示輸出數據源的catalog * * @throws Exception */
    public void print() throws Exception {
        // 獲取連接
        Connection connection = dataSource.getConnection();
        // 輸出catalog
        System.out.println(this.getClass().getSimpleName() + " ->" + connection.getCatalog());
        // 關閉連接
        connection.close();
    }
}
複製代碼

主數據源示例類

@Service
@DataSourceSwitch("master")
public class MasterDataSourceSampleService {
    /** * DataSource Instance */
    @Autowired
    private DataSource dataSource;
    /** * Slave Sample Service */
    @Autowired
    private SlaveDataSourceSampleService slaveDataSourceSampleService;

    /** * 演示輸出主數據源catalog * 調用從數據源類演示輸出catalog * * @throws Exception */
    public void print() throws Exception {
        Connection connection = dataSource.getConnection();
        System.out.println(this.getClass().getSimpleName() + " ->" + connection.getCatalog());
        connection.close();
        slaveDataSourceSampleService.print();
    }
}
複製代碼
  • 主數據源的示例類內,咱們經過@DataSourceSwitch("master")註解的value進行定位鏈接master數據源數據庫。
  • 一樣在從數據庫的示例類內,咱們也能夠經過@DataSourceSwitch("slave")註解的value進行定位鏈接slave數據源數據庫。

單元測試示例

在上面的測試示例中,咱們使用交叉的方式進行驗證數據源路由是否能夠正確的進行切換,能夠編寫一個單元測試進行驗證結果,以下所示:

@Autowired
private MasterDataSourceSampleService masterDataSourceSampleService;
@Test
public void contextLoads() throws Exception {
	masterDataSourceSampleService.print();
}
複製代碼

運行上面測試方法,結果以下所示:

MasterDataSourceSampleService ->test
2019-04-04 10:20:45.407  INFO 7295 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-2 - Starting...
2019-04-04 10:20:45.411  INFO 7295 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-2 - Start completed.
SlaveDataSourceSampleService ->oauth2
複製代碼

單次執行數據源切換沒有任何的問題,master數據源獲取catalog輸出後,調用slave示例類進行輸出catalog

ApiBoot DataSource Switch會在項目啓動時首先初始化master節點DataSource實例,其餘實例會在第一次調用時進行初始化。

壓力性能測試

單次執行單線程操做沒有問題,不表明多線程下不會出現問題,在開頭說到過ApiBoot DataSource Switch是線程安全的,因此接下來咱們來驗證這一點,咱們須要添加壓力測試的依賴,以下所示:

<dependency>
  <groupId>org.databene</groupId>
  <artifactId>contiperf</artifactId>
  <version>2.3.4</version>
  <scope>test</scope>
</dependency>
複製代碼

接下來把上面的單元測試代碼改造下,以下所示:

// 初始化壓力性能測試對象
@Rule
public ContiPerfRule i = new ContiPerfRule();

@Autowired
private MasterDataSourceSampleService masterDataSourceSampleService;
/** * 開啓500個線程執行10000次 */
@Test
@PerfTest(invocations = 10000, threads = 500)
public void contextLoads() throws Exception {
  masterDataSourceSampleService.print();
}
複製代碼

測試環境:

硬件:i七、16G、256SSD

系統:OS X

整個過程大約是10秒左右,ApiBoot DataSource Switch並無發生出現切換錯亂的狀況。

注意事項

  1. 在使用ApiBoot DataSource Switch時須要添加對應數據庫的依賴
  2. 若是使用Druid鏈接池,不要配置使用druid-starter的依賴,請使用druid依賴。
  3. 配置poolName時不要添加特殊字符、中文、中橫線等。
相關文章
相關標籤/搜索