首页 > 其他分享 >ShardingSphere实现读写分离

ShardingSphere实现读写分离

时间:2023-01-19 10:07:43浏览次数:58  
标签:jdbc ShardingSphere 读写 分离 数据源 slave1 user slave2 com


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

文章目录

  • ​​前提条件​​
  • ​​1、创建SpringBoot程序​​
  • ​​1.1、创建项目​​
  • ​​1.2、添加依赖​​
  • ​​1.3、创建实体类​​
  • ​​1.4、创建Mapper​​
  • ​​1.5、Controller​​
  • ​​1.6、配置读写分离​​
  • ​​2、测试​​
  • ​​2.1、读写分离测试​​
  • ​​2.2、事务测试​​
  • ​​2.3、负载均衡测试​​


完整代码已上传

​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.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
<version>5.1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</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<User> 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​

ShardingSphere实现读写分离_数据源

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

2.2、事务测试

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

  • 不添加​​@Transactional​​​:​​insert​​​对主库操作,​​select​​对从库操作
  • 添加​​@Transactional​​​:则​​insert​​​和​​select​​均对主库操作
  • 注意: 如果在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());
}

ShardingSphere实现读写分离_spring boot_02

2.3、负载均衡测试

load-balancer-name: alg_round  # 轮询

ShardingSphere实现读写分离_数据源_03

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

load-balancer-name: alg_weight  # 权重

ShardingSphere实现读写分离_java_04

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

load-balancer-name: alg_random # 随机

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


到此,本章内容就介绍完啦,如果有帮助到你 欢迎点个赞

标签:jdbc,ShardingSphere,读写,分离,数据源,slave1,user,slave2,com
From: https://blog.51cto.com/u_14452299/6019768

相关文章