• ShardingSphere实现读写分离


    把思考付诸实践,以实践提升思考


    完整代码已上传 Gitee Spring整合常用组件

    前提条件

    MySQL主从同步已搭建完成。参考链接

    相关DDL:

    CREATE DATABASE db_user;
    USE db_user;
    CREATE TABLE t_user (
     id BIGINT AUTO_INCREMENT,
     uname VARCHAR(30),
     PRIMARY KEY (id)
    );
    INSERT INTO t_user(uname) VALUES('zhang3');
    INSERT INTO t_user(uname) VALUES(@@hostname);
    

    1、创建SpringBoot程序

    1.1、创建项目

    项目名:sharding-jdbc-demo

    SpringBoot版本:2.5.9

    1.2、添加依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.apache.shardingspheregroupId>
            <artifactId>shardingsphere-jdbc-core-spring-boot-starterartifactId>
            <version>5.1.1version>
        dependency>
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <scope>runtimescope>
        dependency>
        <dependency>
            <groupId>com.baomidougroupId>
            <artifactId>mybatis-plus-boot-starterartifactId>
            <version>3.3.1version>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
        dependency>
    dependencies>
    

    1.3、创建实体类

    package org.example.entity;
    
    import com.baomidou.mybatisplus.annotation.IdType;
    import com.baomidou.mybatisplus.annotation.TableId;
    import com.baomidou.mybatisplus.annotation.TableName;
    import lombok.Data;
    
    /**
     * @description: PO实体类
     * @author: yh
     * @date: 2022/9/18
     */
    @TableName("t_user")
    @Data
    public class User {
        @TableId(type = IdType.AUTO)
        private Long id;
        private String uname;
    }
    

    1.4、创建Mapper

    @Mapper
    public interface UserMapper extends BaseMapper<User> {
    }
    

    1.5、Controller

    @RestController
    @RequestMapping(value = "/user")
    public class UserController {
        @Resource
        private UserMapper userMapper;
    
        /**
         * 插入数据,测试是否写入master
         * 如果开启事务,读会走master数据源
         * @author: yh
         * @date: 2022/9/18
         */
    //    @Transactional
        @GetMapping("/insert")
        public void userInsert(){
            User u = new User();
            u.setUname("西门庆"+System.currentTimeMillis());
            userMapper.insert(u);
    //        List users = userMapper.selectList(null);
    //        System.out.println(users.size());
        }
    
        /**
         * 查询
         * @author: yh
         * @date: 2022/9/18
         */
        @GetMapping("/selectAll")
        public void selectAll(){
            userMapper.selectList(null);
        }
    }
    

    1.6、配置读写分离

    application.yml:

    spring:
      application:
        name: sharging-jdbc-demo
      profiles:
        active: dev
    

    application-dev.yml:

    # 读写分离配置
    spring:
      shardingsphere:
        datasource:
          # 配置真实数据源
          names: master,slave1,slave2
          # 配置第 1 个数据源
          master:
            driver-class-name: com.mysql.jdbc.Driver
            jdbc-url: jdbc:mysql://192.168.1.1:3306/db_user
            password: 123456
            type: com.zaxxer.hikari.HikariDataSource
            username: root
          # 配置第 2 个数据源
          slave1:
            driver-class-name: com.mysql.jdbc.Driver
            jdbc-url: jdbc:mysql://192.168.1.1:3307/db_user
            password: 123456
            type: com.zaxxer.hikari.HikariDataSource
            username: root
          # 配置第 3 个数据源
          slave2:
            driver-class-name: com.mysql.jdbc.Driver
            jdbc-url: jdbc:mysql://192.168.1.1:3308/db_user
            password: 123456
            type: com.zaxxer.hikari.HikariDataSource
            username: root
        mode:
          # 内存模式
          type: Memory
        # 打印sql
        props:
          sql-show: true
        rules:
          readwrite-splitting:
            data-sources:
              myds:
                # 读数据源负载均衡算法名称
                load-balancer-name: alg_round
                props:
                  # 读数据源名称,多个从数据源用逗号分隔
                  read-data-source-names: slave1,slave2
                  # 写数据源名称
                  write-data-source-name: master
                # 读写分离类型,如: Static,Dynamic
                type: Static
            load-balancers:
              # 定义负载均衡算法:随机,轮询,权重
              alg_random:
                type: RANDOM
              alg_round:
                type: ROUND_ROBIN
              alg_weight:
                props:
                  slave1: 1
                  slave2: 2
                type: WEIGHT
    

    2、测试

    2.1、读写分离测试

    启动App Server,请求http://127.0.0.1:8080/user/insert

    在这里插入图片描述

    写入主数据源后,查询主数据库中数据是否写入,从数据库数据是否正常同步

    2.2、事务测试

    为了保证主从库间的事务一致性,避免跨服务的分布式事务,ShardingSphere-JDBC的主从模型中,事务中的数据读写均用主库

    • 不添加@Transactionalinsert对主库操作,select对从库操作
    • 添加@Transactional:则insertselect均对主库操作
    • 注意: 如果在JUnit环境下的@Transactional注解,默认情况下就会对事务进行回滚(即使在没加注解@Rollback,也会对事务回滚)
    @Transactional
    @GetMapping("/insert")
    public void userInsert(){
        User u = new User();
        u.setUname("西门庆"+System.currentTimeMillis());
        userMapper.insert(u);
        List<User> users = userMapper.selectList(null);
        System.out.println(users.size());
    }
    

    在这里插入图片描述

    2.3、负载均衡测试

    load-balancer-name: alg_round  # 轮询
    

    在这里插入图片描述

    查询6次结果:slave1,slave2,slave1,slave2,slave1,slave2。结果轮询

    load-balancer-name: alg_weight  # 权重
    

    在这里插入图片描述

    访问9次:slave1数据库3次,slave2数据库6次。权重 1:2

    load-balancer-name: alg_random # 随机
    

    访问6次:slave2,slave2,slave1,slave2,slave2,slave1,slave1。结果随机


    到此,本章内容就介绍完啦,如果有帮助到你 欢迎点个赞👍👍吧!!您的鼓励是博主的最大动力! 有问题评论区交流。

  • 相关阅读:
    【附源码】计算机毕业设计java医院疫情管理系统设计与实现
    JavaScript系列之逻辑运算符
    解密【NIOIP 2022 普及组】
    MindSpore报错显示parameter没有zero属性
    MXNet-图像分类(symbol版本)【附源码】
    【小笔记】面对一个没搞过的任务,如何选择合适的算法模型?
    数据结构——单向链表
    【刷题篇】回溯算法(广度优先搜索(一))
    ES之倒排索引
    html css制作正六边形
  • 原文地址:https://blog.csdn.net/weixin_43847283/article/details/126923511