ApiBoot DataSource Switch 使用文档

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: ApiBoot是一款基于SpringBoot1.x,2.x的接口服务集成基础框架, 内部提供了框架的封装集成、使用扩展、自动化完成配置,让接口开发者可以选着性完成开箱即用, 不再为搭建接口框架而犯愁,从而极大的提高开发效率。

ApiBoot是一款基于SpringBoot1.x,2.x的接口服务集成基础框架, 内部提供了框架的封装集成、使用扩展、自动化完成配置,让接口开发者可以选着性完成开箱即用, 不再为搭建接口框架而犯愁,从而极大的提高开发效率。

ApiBoot DataSource Switch

顾名思义,DataSource Switch是用于数据源选择切换的框架,这是一款基于Spring AOP切面指定注解实现的,通过简单的数据源注解配置就可以完成访问时的自动切换,DataSource Switch切换过程中是线程安全的。

添加依赖

使用DataSource Switch很简单,在pom.xml配置文件内添加如下依赖:

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

ApiBoot所提供的依赖都不需要添加版本号,具体查看ApiBoot版本依赖

集成数据源实现

目前ApiBoot DataSource Switch集成了DruidHikariCP两种数据源实现依赖,在使用方面也有一定的差异,因为每一个数据源的内置参数不一致。

  • 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自带的,配置参数请访问HikariCP

单主配置

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修改为main

主从配置

如果你的项目内存在单主单从一主多从的配置方式,如下所示:

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

测试环境:

硬件:i7、16G、256SSD

系统:OS X

整个过程大约是10秒左右,ApiBoot DataSource Switch并没有发生出现切换错乱的情况。

注意事项

  1. 在使用ApiBoot DataSource Switch时需要添加对应数据库的依赖
  2. 如果使用Druid连接池,不要配置使用druid-starter的依赖,请使用druid依赖。
  3. 配置poolName时不要添加特殊字符、中文、中横线等。
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
4月前
|
监控 druid Java
Druid【SpringBoot集成】监控数据库报错 Failed to bind properties under ‘‘ to javax.sql.DataSource 解决(含配置源码)
Druid【SpringBoot集成】监控数据库报错 Failed to bind properties under ‘‘ to javax.sql.DataSource 解决(含配置源码)
226 0
|
1月前
|
Java 数据库
【问题记录(已解决)】springboot整合ssm报错‘url‘ attribute is not specified and no embedded datasource
【问题记录(已解决)】springboot整合ssm报错‘url‘ attribute is not specified and no embedded datasource
|
8月前
|
druid Java
SpringBoot整合Druid报错记录:Failed to configure a DataSource: ‘url‘ attribute is not specified and no embe
SpringBoot整合Druid报错记录:Failed to configure a DataSource: ‘url‘ attribute is not specified and no embe
|
10月前
|
JSON Java 数据库连接
IDEA在写Mybatis时遇到了Could not autowire. No beans of 'xxxx' type found 的错误提示
IDEA在写Mybatis时遇到了Could not autowire. No beans of 'xxxx' type found 的错误提示
158 0
QGS
|
11月前
浅谈Spring6引入外部Jdbc.properties配置文件
SpringConfig.xml配置 xmlns:context="http://www.springframework.org/schema/context" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context <!--引入外部的properties文件-->
QGS
72 0
springboot: Failed to bind properties under ‘spring.datasource’ to javax.sql.DataSource
springboot: Failed to bind properties under ‘spring.datasource’ to javax.sql.DataSource
springboot: Failed to bind properties under ‘spring.datasource’ to javax.sql.DataSource
|
XML Java 数据库连接
【异常】Mybatis中,SpringMVC中,SpringBoot项目中,出现There is no getter for property named 'xxxxxx'报错的解决方法
Mybatis中,SpringMVC中,SpringBoot项目中,出现There is no getter for property named 'xxxxxx'报错的解决方法
227 0
|
安全 Java 关系型数据库
ApiBoot零代码整合Spring Security的JDBC方式获取AccessToken
`ApiBoot Security`内部提供了**两种方式**进行读取需要认证的用户信息,在之前的文章中讲到过`ApiBoot Security`使用`内存方式(memory)`**不写一行代码**就可以实现用户的认证并获取`AccessToken`,那我们使用`JDBC`方式是不是也是这么的简单呢?
ApiBoot零代码整合Spring Security的JDBC方式获取AccessToken
|
Java Maven 开发工具
报错解决:Could not resolve placeholder ‘spring.datasource.url‘ in value “${spring.datasource.url}“
报错解决:Could not resolve placeholder ‘spring.datasource.url‘ in value “${spring.datasource.url}“
1878 0
报错解决:Could not resolve placeholder ‘spring.datasource.url‘ in value “${spring.datasource.url}“
|
Java 数据库
SpringBoot 项目启动出错:Failed to configure a DataSource: ‘url‘ attribute is not specified and no embedde
SpringBoot 项目启动出错:Failed to configure a DataSource: ‘url‘ attribute is not specified and no embedde
318 0