美文网首页IT必备技能Mybatis-plus
四 . springboot实现数据库读写分离

四 . springboot实现数据库读写分离

作者: 任未然 | 来源:发表于2019-09-26 09:21 被阅读0次

    一 . 概述

    dynamic-datasource的具体介绍请查看dynamic-datasource官网
    dynamic-datasource-spring-boot-starter 是一个基于springboot的快速集成多数据源的启动器。其支持 Jdk 1.7+, SpringBoot 1.4.x 1.5.x 2.0.x。

    1.1 特性

    • 数据源分组,适用于多种场景 纯粹多库 读写分离 一主多从 混合模式。
    • 内置敏感参数加密和启动初始化表结构schema数据库database。
    • 提供对Druid,Mybatis-Plus,P6sy,Jndi的快速集成。
    • 简化Druid和HikariCp配置,提供全局参数配置。
    • 提供自定义数据源来源接口(默认使用yml或properties配置)。
    • 提供项目启动后增减数据源方案。
    • 提供Mybatis环境下的 纯读写分离 方案。
    • 使用spel动态参数解析数据源,如从session,header或参数中获取数据源。(多租户架构神器)
    • 提供多层数据源嵌套切换。(ServiceA >>> ServiceB >>> ServiceC,每个- - Service都是不同的数据源)
    • 提供 不使用注解 而 使用 正则 或 spel 来切换数据源方案(实验性功能)。

    1.2 约定

    • 本框架只做 切换数据源 这件核心的事情,并不限制你的具体操作,切换了- - 数据源可以做任何CRUD。
    • 配置文件所有以下划线 _ 分割的数据源 首部 即为组的名称,相同组名称的- - 数据源会放在一个组下。
    • 切换数据源可以是组名,也可以是具体数据源名称。组名则切换时采用负载均衡算法切换。
    • 默认的数据源名称为 master ,你可以通过 spring.datasource.dynamic.primary 修改。
    • 方法上的注解优先于类上注解。

    二 . spring-boot整合

    2.1 步骤一: 导入工具包

    <!--        导入配置文件处理器-->
    <!--       动态数据库连接包-->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
                <version>2.5.6</version>
            </dependency>
    

    2.2 yml配置

    spring:
      datasource:
        dynamic:
          primary: master #设置默认的数据源或者数据源组,默认值即为master
          strict: false #设置严格模式,默认false不启动. 启动后在未匹配到指定数据源时候回抛出异常,不启动会使用默认数据源.
          datasource:
            master:
              url: jdbc:mysql://xx.xx.xx.xx:3306/dynamic
              username: root
              password: 123456
              driver-class-name: com.mysql.jdbc.Driver
            slave_1:
              url: jdbc:mysql://xx.xx.xx.xx:3307/dynamic
              username: root
              password: 123456
              driver-class-name: com.mysql.jdbc.Driver
            slave_2:
              url: ENC(xxxxx) # 内置加密,使用请查看详细文档
              username: ENC(xxxxx)
              password: ENC(xxxxx)
              driver-class-name: com.mysql.jdbc.Driver
              schema: db/schema.sql # 配置则生效,自动初始化表结构
              data: db/data.sql # 配置则生效,自动初始化数据
              continue-on-error: true # 默认true,初始化失败是否继续
              separator: ";" # sql默认分号分隔符
              
           #......省略
           #以上会配置一个默认库master,一个组slave下有两个子库slave_1,slave_2
    

    其他主从方式配置模板

    # 多主多从                      纯粹多库(记得设置primary)                   混合配置
    spring:                               spring:                               spring:
      datasource:                           datasource:                           datasource:
        dynamic:                              dynamic:                              dynamic:
          datasource:                           datasource:                           datasource:
            master_1:                             mysql:                                master:
            master_2:                             oracle:                               slave_1:
            slave_1:                              sqlserver:                            slave_2:
            slave_2:                              postgresql:                           oracle_1:
            slave_3:                              h2:                                   oracle_2:
    

    2.3 数据源切换使用

    @DS 可以注解在方法上和类上,同时存在方法注解优先于类上注解。
    强烈建议只注解在service实现上。

    注解 结果
    没有@DS 默认数据源
    @DS("dsName") dsName可以为组名也可以为具体某个库的名称

    示例

    在service实现层

    @Service
    @DS("slave")
    public class UserServiceImpl implements UserService {
    
      @Autowired
      private JdbcTemplate jdbcTemplate;
    
      public List<Map<String, Object>> selectAll() {
        return  jdbcTemplate.queryForList("select * from user");
      }
      
      @Override
      @DS("slave_1")
      public List<Map<String, Object>> selectByCondition() {
        return  jdbcTemplate.queryForList("select * from user where age >10");
      }
    }
    

    三. 第三方继承

    3.1 集成Druid

    springBoot2.x默认使用HikariCP,但在国内Druid的使用者非常庞大,此项目特地对其进行了适配,完成多数据源下使用Druid进行监控。
    注意 :主从可以使用不同的数据库连接池,如 master使用Druid监控,从库使用HikariCP。如果不配置连接池type类型,默认是 Druid优先于HikariCP 。

    3.1.1 项目引入 druid-spring-boot-starter 依赖

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.1.10</version>
    </dependency>
    

    3.1.2 排除 原生Druid的快速配置类。

    @SpringBootApplication(exclude = DruidDataSourceAutoConfigure.class)
    public class Application {
      public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
      }
    }
    

    某些springBoot的版本上面可能无法排除(尝试使用以下方式排除)

    spring:
      autoconfigure:
        exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
    
    • 为什么要排除DruidDataSourceAutoConfigure ?

    DruidDataSourceAutoConfigure会注入一个DataSourceWrapper,其会在原生的spring.datasource下找url,username,password等。而我们动态数据源的配置路径是变化的。

    3.1.2 YML配置

    spring:
      datasource:
        druid:
          stat-view-servlet:
            enabled: true
            url-pattern: /druid/*
            #  是否可以使用重置功能
            reset-enable: false
            login-username: admin
            login-password: admin
            #  允许访问的id
            allow: 127.0.0.1
            #  和名单
            deny: ""
        dynamic:
          druid: #以下是全局默认值,可以全局更改
            # druid 配置
            # 初始化连接数
            initial-size: 5
            # 最大连接数
            max-active: 10
            # 最少连接数
            min-idle: 3
            #      配置监控统计拦截器 日志配置  Slf4j  logback
            #      stat 监控数据库性能
            #      wall  用于防火墙
            #      日志先关 slf4j  logback  log4j  log4j2
            filters: stat,wall,slf4j
            web-stat-filter:
              enabled: true
              url-pattern:  /*
              # 排除不拦截的 请求
              exclusions: "*.js,/druid/*"
          datasource:
            master:
              username: root
              password: 123456
              driver-class-name: com.mysql.jdbc.Driver
              url: jdbc:mysql://106.13.221.151:3316/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
              druid: # 以下参数针对每个库可以重新设置druid参数
                initial-size: 5
                validation-query: select 1 FROM DUAL #比如oracle就需要重新设置这个
                public-key: #(非全局参数)设置即表示启用加密,底层会自动帮你配置相关的连接参数和filter。
            slave_1:
              username: ****
              password: ****
              driver-class-name: com.mysql.jdbc.Driver
              url: jdbc:mysql://106.13.221.151:3317/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
              druid:
                # druid 配置
                # 初始化连接数
                initial-size: 5
                # 最大连接数
                max-active: 10
                # 最少连接数
                min-idle: 3
    

    程序入口开启mappe扫描

    @SpringBootApplication(exclude = DruidDataSourceAutoConfigure.class)
    @MapperScan("com.example.demo.mapper")
    public class DemoApplication {
        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    }
    

    3.2 集成HikariCP

    HikariCP官方地址
    SpringBoot 2.+ 默认引入了HikariCP,除非对版本有要求无需再次引入。
    使用SpringBoot 1.5.x的版本需手动引入,对应的版本请根据自己环境和HikariCP官方地址自行选择。

    3.2.1 YML配置

    spring:
      datasource:
        dynamic:
          hikari:  # 全局hikariCP参数,所有值和默认保持一致。(现已支持的参数如下,不清楚含义不要乱设置)
            catalog:
            connection-timeout:
            validation-timeout:
            idle-timeout:
            leak-detection-threshold:
            max-lifetime:
            max-pool-size:
            min-idle:
            initialization-fail-timeout:
            connection-init-sql:
            connection-test-query:
            dataSource-class-name:
            dataSource-jndi-name:
            schema:
            transaction-isolation-name:
            is-auto-commit:
            is-read-only:
            is-isolate-internal-queries:
            is-register-mbeans:
            is-allow-pool-suspension:
            data-source-properties: #以下属性仅为演示(默认不会引入)
              serverTimezone: Asia/Shanghai
              characterEncoding: utf-8
              useUnicode: true
              useSSL: false
              autoReconnect: true
              cachePrepStmts: true
              prepStmtCacheSize: 250
              prepStmtCacheSqlLimit: 2048
              useServerPrepStmts: true
              useLocalSessionState: true
              rewriteBatchedStatements: true
              cacheResultSetMetadata: true
              cacheServerConfiguration: true
              elideSetAutoCommits: true
              maintainTimeStats: false
              allowPublicKeyRetrieval: true
            health-check-properties:
          datasource:
            master:
              username: root
              password: 123456
              driver-class-name: com.mysql.jdbc.Driver
              url: jdbc:mysql://xx.xx.xx.xx:3306/dynamic?characterEncoding=utf8&useSSL=false
              hikari: # 以下参数针对每个库可以重新设置hikari参数
                max-pool-size:
                idle-timeout:
    #           ......
    

    相关文章

      网友评论

        本文标题:四 . springboot实现数据库读写分离

        本文链接:https://www.haomeiwen.com/subject/owrhuctx.html