ShardingSphere 5.x 系列【5】Spring Boot 3.1 集成Sharding Sphere-JDBC并实现读写分离

有道无术,术尚可求,有术无道,止于术。

本系列Spring Boot 版本 3.1.0

本系列ShardingSphere 版本 5.4.0

源码地址:https://gitee.com/pearl-organization/study-sharding-sphere-demo

文章目录

    • 1. 概述
    • 2. 使用限制
    • 3. 案例演示
      • 3.1 一主双从
      • 3.2 项目搭建
      • 3.3 配置
      • 3.4 测试
    • 4. 负载均衡算法
      • 4.1 轮询
      • 4.2 随机
      • 4.3 权重
      • 4.4 自定义

1. 概述

读写分离是一种数据库部署架构,将数据库拆分为读库写库写库负责处理事务性的增删改操作,读库负责处理查询操作,适用于查询多,写入少的应用系统。读写分离将查询请求均匀的分散到多个从库中,可以提升数据库的吞吐量,可以提高系统的可用性,当宕机一台数据库不影响系统的正常运行。

读写分离的实现基于数据的的主从部署架构,一主多从读写分离部署示例:
在这里插入图片描述

同时读写分离也带来了一些问题:

  • 数据一致性:多个主库之间的数据一致性,以及主库与从库之间的数据一致性
  • 复杂性:开发和运维操作变得更加复杂

2. 使用限制

ShardingSphere提供了读写分离功能管理主从数据库,实现透明化的读写分离功能,让用户像使用一个数据库一样使用主从架构的数据库,并提供了多种负载均衡策略,用于将查询请求转发至不同从库。

使用限制:

  • 目前仅支持一主多从
  • 不处理主库和从库的数据同步
  • 不处理主库和从库的数据同步延迟导致的数据不一致
  • 不支持主库多写
  • 不处理主从库间的事务一致性,主从模型中,事务中的数据读写均用主库

3. 案例演示

3.1 一主双从

使用MySql搭建一主双从,并同步一张用于测试的订单表:

在这里插入图片描述

3.2 项目搭建

创建一个Spring Boot基础工程,并引入相关依赖。

Parent

	<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.1.0</version><relativePath/> <!-- lookup parent from repository --></parent>

Spring Boot基础依赖:

		<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>

Mybatis Plus

		<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.5</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency>

ShardingSphere5.3.0及之后的版本,考虑到维护兼容成本,更加专心于自身功能迭代,移除了Spring Boot Starter,所以只能引入 ShardingSphere-JDBC核心包:

		<dependency><groupId>org.apache.shardingsphere</groupId><artifactId>shardingsphere-jdbc-core</artifactId><version>5.4.0</version></dependency><!--java.lang.ClassNotFoundException: com.sun.xml.internal.bind.v2.ContextFactory--><dependency><groupId>org.glassfish.jaxb</groupId><artifactId>jaxb-runtime</artifactId><version>2.3.8</version></dependency>

最后使用代码工具生成订单相关业务代码:
在这里插入图片描述

3.3 配置

ShardingSphere-JDBC5.3.0及之后的版本不再提供Spring Boot Starter,所以配置方面有较大的变化,目前只支持Java APIYAML 进行配置。

ShardingSphere 提供了 JDBC 驱动,首先需要在application.yml中配置ShardingSphereDriver

server:port: 8080
spring:datasource:# 配置 DataSource Driverdriver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver# 指定 YAML 配置文件url: jdbc:shardingsphere:classpath:readwrite-splitting-config.yml # 读写分离配置文件

application.yml同级目录下创建readwrite-splitting-config.yml续写分离配置文件,在该文件中,首先添加数据源配置:

# 数据源配置
dataSources:# 主库write_ds: # 逻辑名称dataSourceClassName: com.zaxxer.hikari.HikariDataSourcedriverClassName: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.56.101:3306/testusername: rootpassword: "root"# 从库1read_ds_0:dataSourceClassName: com.zaxxer.hikari.HikariDataSourcedriverClassName: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.56.101:3307/testusername: rootpassword: "root"# 从库2read_ds_1:dataSourceClassName: com.zaxxer.hikari.HikariDataSourcedriverClassName: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.56.101:3308/testusername: rootpassword: "root"

然后添加读写分离规则、从库负载均衡相关配置:

# 规则配置
rules:# 读写分离配置- !READWRITE_SPLITTINGdataSources: # 数据源readwrite_ds: # 读写分离逻辑数据源名称writeDataSourceName: write_ds # 写库数据源名称readDataSourceNames: # 读库数据源名称,多个从数据源用逗号分隔- read_ds_0- read_ds_1transactionalReadQueryStrategy: PRIMARY # 事务内读请求的路由策略,可选值:PRIMARY(路由至主库)、FIXED(同一事务内路由至固定数据源)、DYNAMIC(同一事务内路由至非固定数据源)。默认值:DYNAMICloadBalancerName: read # 负载均衡自定义算法名称# 负载均衡算法loadBalancers:read:  # 自定义的算法名称type: RANDOM # 负载均衡算法类型
props:# 是否打印 SQLsql-show: true

3.4 测试

添加查询、新增测试访问接口:

@RestController
@RequestMapping("/order")
@RequiredArgsConstructor
public class OrderController {private final OrderService orderService;@GetMapping("/list")public List<OrderEntity> list() {return orderService.list();}@GetMapping("/save")public Object save() {OrderEntity orderEntity=new OrderEntity();orderEntity.setPhone(18888888888L);orderEntity.setAddress("湖南长沙");orderEntity.setOrderTime(LocalDateTime.now());orderEntity.setProductId(1L);orderEntity.setOrderTime(LocalDateTime.now());orderEntity.setId(IdUtil.getSnowflakeNextId());orderService.save(orderEntity);return "操作成功";}
}   

启动项目,多次访问新增接口,可以看到都是走的主库:
在这里插入图片描述
多次访问查询接口,可以看到都是走的从库:
在这里插入图片描述

4. 负载均衡算法

负载均衡(Load Balancing)用于将工作负载分配到多个计算资源,以提高性能、可靠性、可扩展性。读写分离环境下,对于多台从库的访问策略,ShardingSphere内置了多种负载均衡算法,满足用户绝大多数业务场景的需要。

4.1 轮询

按顺序轮流对读库进行访问。

# 规则配置
rules:# 读写分离配置- !READWRITE_SPLITTINGdataSources: # 数据源readwrite_ds: # 读写分离逻辑数据源名称writeDataSourceName: write_ds # 写库数据源名称readDataSourceNames: # 读库数据源名称,多个从数据源用逗号分隔- read_ds_0- read_ds_1transactionalReadQueryStrategy: PRIMARY # 事务内读请求的路由策略,可选值:PRIMARY(路由至主库)、FIXED(同一事务内路由至固定数据源)、DYNAMIC(同一事务内路由至非固定数据源)。默认值:DYNAMICloadBalancerName: read # 负载均衡自定义算法名称# 负载均衡算法loadBalancers:read:  # 自定义的算法名称type: ROUND_ROBIN # 负载均衡算法类型

4.2 随机

随机选取一台读库进行访问。

# 规则配置
rules:# 读写分离配置- !READWRITE_SPLITTINGdataSources: # 数据源readwrite_ds: # 读写分离逻辑数据源名称writeDataSourceName: write_ds # 写库数据源名称readDataSourceNames: # 读库数据源名称,多个从数据源用逗号分隔- read_ds_0- read_ds_1transactionalReadQueryStrategy: PRIMARY # 事务内读请求的路由策略,可选值:PRIMARY(路由至主库)、FIXED(同一事务内路由至固定数据源)、DYNAMIC(同一事务内路由至非固定数据源)。默认值:DYNAMICloadBalancerName: read # 负载均衡自定义算法名称# 负载均衡算法loadBalancers:read:  # 自定义的算法名称type: RANDOM # 负载均衡算法类型

4.3 权重

给读库分配权重,权重高的优先访问。

# 规则配置
rules:# 读写分离配置- !READWRITE_SPLITTINGdataSources: # 数据源readwrite_ds: # 读写分离逻辑数据源名称writeDataSourceName: write_ds # 写库数据源名称readDataSourceNames: # 读库数据源名称,多个从数据源用逗号分隔- read_ds_0- read_ds_1transactionalReadQueryStrategy: PRIMARY # 事务内读请求的路由策略,可选值:PRIMARY(路由至主库)、FIXED(同一事务内路由至固定数据源)、DYNAMIC(同一事务内路由至非固定数据源)。默认值:DYNAMICloadBalancerName: read # 负载均衡自定义算法名称# 负载均衡算法loadBalancers:read:  # 自定义的算法名称type: WEIGHT # 负载均衡算法类型# 属性props:# 属性名使用读库名称,参数填写读库对应的权重值。权重参数范围最小值 > 0,合计 <= Double.MAX_VALUE。# 读库名称: 权重read_ds_0: 9read_ds_1: 1

4.4 自定义

考虑到业务场景的复杂性,提供基于SPI 接口实现符合自己业务需要的负载均衡算法。

ShardingSphere提供了读库负载均衡算法接口ReadQueryLoadBalanceAlgorithm,用户根据自定的算法返回一个可访问的读库。

public interface ReadQueryLoadBalanceAlgorithm extends ShardingSphereAlgorithm {/**** @param name 读写分离逻辑数据源名称* @param writeDataSourceName 写库数据源名称* @param readDataSourceNames 读库数据源名称集合* @return 命中的读库名称*/String getDataSource(String name, String writeDataSourceName, List<String> readDataSourceNames) {}

实现ReadQueryLoadBalanceAlgorithm接口,自定义一个负载均衡算法:

public final class CustomReadQueryLoadBalanceAlgorithm implements ReadQueryLoadBalanceAlgorithm {/*** 配置类中的props属性*     # 负载均衡算法*     loadBalancers:*       read:  # 自定义的算法名称*         type: CUSTOM # 负载均衡算法类型*         # 属性*         props:*           # 属性名使用读库名称,参数填写读库对应的权重值。权重参数范围最小值 > 0,合计 <= Double.MAX_VALUE。*           # 读库名称: 权重*           read_ds_0: 9*           read_ds_1: 1*/private Properties props;// 将配置类props属性赋值给当前对象 public void init(Properties props) {this.props = props;}public String getDataSource(String name, String writeDataSourceName, List<String> readDataSourceNames) {// 自定义算法逻辑(这里演示,直接返回第一个)return readDataSourceNames.get(0);}/*** 声明算法类型*/public String getType() {return "CUSTOM";}/*** 是否是默认*/public boolean isDefault() {return false;}public Properties getProps() {return props;}public void setProps(Properties props) {this.props = props;}
}

resources目录下创建META-INF\services文件夹,并创建文件,名称为org.apache.shardingsphere.readwritesplitting.spi.ReadQueryLoadBalanceAlgorithm,文件内容为自定义算法类全限定类名:

com.pearl.shardingsphere.rw.algorithm.CustomReadQueryLoadBalanceAlgorithm

在这里插入图片描述
配置类修改算法类型为自定义:

# 规则配置
rules:# 读写分离配置- !READWRITE_SPLITTINGdataSources: # 数据源readwrite_ds: # 读写分离逻辑数据源名称writeDataSourceName: write_ds # 写库数据源名称readDataSourceNames: # 读库数据源名称,多个从数据源用逗号分隔- read_ds_0- read_ds_1transactionalReadQueryStrategy: PRIMARY # 事务内读请求的路由策略,可选值:PRIMARY(路由至主库)、FIXED(同一事务内路由至固定数据源)、DYNAMIC(同一事务内路由至非固定数据源)。默认值:DYNAMICloadBalancerName: read # 负载均衡自定义算法名称# 负载均衡算法loadBalancers:read:  # 自定义的算法名称type: CUSTOM # 负载均衡算法类型

访问查询接口,看到使用的都是第一个读库,说明自定义算法生效:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/667931.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Angular 基础] - 数据绑定(databinding)

[Angular 基础] - 数据绑定(databinding) 上篇笔记&#xff0c;关于 Angular 的渲染过程及组件的创建&简单学习&#xff1a;[Angular 基础] - Angular 渲染过程 & 组件的创建 Angular 之中的 databinding 是一个相对而言更加复杂&#xff0c;以及我个人觉得相对而言比…

算法笔记刷题日记——3.简单入门模拟 3.1简单模拟

刷题日记 3.1 简单模拟 此类题型根据题目描述进行代码的编写&#xff0c;考察代码能力&#xff0c;刷题记录如下&#xff1a; B1001 B1032 B1016 B1026 B1046 B1008 B1012 B1018 A1042 A1046 A1065 B1010 A1002 A1009 错题记录 B1008 数组元素循环右移问题 一个数组_A_中存有…

[机缘参悟-145] :一个软件架构师对佛学的理解 -9- 修行的目标和层次:净心、智慧和解脱

目录 前言&#xff1a; 第一层次&#xff08;小乘&#xff09;&#xff1a;净心&#xff0c;摆脱痛苦和烦扰&#xff0c;进入平静和安宁 1.1 什么是净心 1.2 如何达到净心的状态 1.3 "常乐我净" 第二层次&#xff08;中乘&#xff09;&#xff1a;智慧&#xf…

【Spring连载】使用Spring Data访问Redis(十三)----支持类Support Classes

【Spring连载】使用Spring Data访问Redis&#xff08;十三&#xff09;----支持类Support Classes org.springframework.data.redis.support包提供了各种可重复使用的组件&#xff0c;这些组件依赖Redis作为后端存储。目前&#xff0c;该包包含Redis之上的各种基于JDK的接口实现…

SpringMVC精简知识点

SpringMVC 数据格式化基本数据类型和字符串自动转换特殊数据类型和字符串自动转换 验证及国际化应用实例注意事项和使用细节注解的结合使用数据类型转换校验核心类-DatBinder取消某个属性的绑定中文乱码解决处理json和HttpMessageConverter<T>作业布置SpringMVC文件上传自…

day19 初始HTML

什么是HTML HTML&#xff08;Hyper Text Markup Language&#xff09;超文本标记语言 超文本包括&#xff1a;文字、图片、音频、视频、动画等 HTML5&#xff0c;提供了一些新的元素和一些有趣的新特性&#xff0c;同时也建立了一些新的规则。这些元素、特性和规则的建立&…

【Linux】进程间通信 --管道通信

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法…感兴趣就关注我吧&#xff01;你定不会失望。 本篇导航 0. 进程间通信原理1. 匿名管道1.1 通信原理1.2 接口介绍 2. 命名管道2.1 接口介绍 3. 共享内存3.1 通信原理3.2 接口介绍 0. 进…

用户访问一个购物网站时TCP/IP五层参考模型中每一层的功能

当用户访问一个购物网站时&#xff0c;网络上的每一层都会涉及不同的协议&#xff0c;具体网络模型如下图所示。 以下是每个网络层及其相关的协议示例&#xff1a; 物理层&#xff1a;负责将比特流传输到物理媒介上&#xff0c;例如电缆或无线信号。所以在物理层&#xff0c;可…

Dell服务器iDRAC9忘记密码, 通过RACADM工具不重启 重置密码

系列文章目录 文章目录 系列文章目录前言一、RACADM工具二、linux环境1.解压安装RACADM工具测试RACADM工具重置iDRAC密码 Windows环境 前言 一、RACADM工具 RACADM工具 官网参考信息 https://www.dell.com/support/kbdoc/zh-cn/000126703/%E5%A6%82%E4%BD%95-%E9%87%8D%E7%BD…

异步八种方式提高性能

异步的八种实现方式 线程ThreadFuture异步框架CompletableFutureSpring注解AsyncSpring ApplicationEvent事件消息队列第三方异步框架&#xff0c;比如Hutool的ThreadUtilGuava异步 一、线程异步 public class AsyncThread extends Thread{Overridepublic void run(){System…

东方博宜1126:英文翻译

题目描述 请将一个数字&#xff0c;翻译成对应的英文。 输入 一个自然数 n。&#xff08;0≤n≤2^31−1&#xff09; 输出 输出这个数的英文&#xff0c;最后不要有多余的空格。 输入样例&#xff1a; 1111111111 输出样例&#xff1a; one billion one hundred and e…

计算机网络-封装成帧透明传输(组帧方法)

文章目录 数据链路层功能概述封装成帧透明传输组帧方法字符计数法字符填充法零比特填充法违规编码法 字符填充法为啥复杂和不兼容 数据链路层功能概述 类似老板让小秘书送文件给别的公司&#xff0c;小秘书告诉傻子怎么把该文件送到别的公司的小秘书&#xff0c;然后别的公司的…

c# File.WriteAllLines 和 File.WriteAllText

File.WriteAllLines 和 File.WriteAllText 都是 C# 中用于写入文本文件的方法&#xff0c;但它们有一些区别。 1. File.WriteAllLines 方法&#xff1a; File.WriteAllLines 方法用于将字符串数组的内容按行写入文本文件。每个数组元素都被写入文件的一行&#xff0c;且方法会…

探索边缘计算的未来:MobileNetV3Small及其在高效图像处理中的创新应用

引言 在不断发展的计算机视觉和深度学习领域中&#xff0c;对于更高效、更强大的神经网络的追求从未停止。在这个领域的领跑者之一是MobileNetV3Small架构&#xff0c;这是MobileNetV3家族的一个变体&#xff0c;以其在处理图像任务方面的高效率和有效性而闻名。本文深入探讨了…

Blender 的重拓扑功能中的参数,

关于 Blender 的重拓扑功能中的一个参数&#xff0c;叫做 Voxel Size R。我会尽量用简单的语言来解释它的含义和作用。 Voxel Size R 是指重拓扑后的网格的分辨率或细节程度。它用来定义 Voxel 的大小&#xff0c;Voxel 是一种用来表示三维空间中的体积元素的单位。重拓扑的过…

Hello 2024C. Grouping Increases(贪心、分类讨论)

我们只需要记录每个数结尾的数是多少&#xff08;有点最长上升子序列的味道&#xff09; 这种子序列的题目很多都是这样的&#xff0c;因为不需要连续很多时候我们只记录最后一个元素是多少。 记 s 为较大子序列结尾当前的数&#xff0c; t 为较小子序列结尾的数&#xff0c;下…

Symbol.toStringTag用法

Symbol.toStringTag 作用 对象上的Symbol.toStringTag属性用于对象toString类型标识 Symbol.toStringTag 解释 对象调用toString方法&#xff0c;如果这个属性存在&#xff0c;它的返回值会出现在toString方法返回的字符串之中&#xff0c;表示对象的类型。 webpack中也有使…

Spring面试

文章目录 Spring面试Spring框架用了什么设计模式&#xff1f;Spring Bean的作用域Spring如何解决循环依赖什么样的循环依赖无法处理构造方法注入 VS setter注入 Spring框架中有哪些不同类型的事件&#xff1f;AOP (Aspect Oriented Program) 切面编程IOC容器BeanFactory 与 App…

修改UnityEngine dll

修改UnityEngine dll 由于有些版本的dll与热重载并不兼容&#xff0c;需要小幅修改代码。 使用dnspy工具 我们使用 dnspy 来修改 dll文件。而dnspy只能在Win下运行&#xff0c;故哪怕是mac版本dll&#xff0c; 你也得先将相应dll复制到Win下后再修改。下载 dnspy&#xff0c…

FastAdmin青动CRM-E售后

应用介绍 一款基于FastAdminThinkPHP和uniapp开发的CRM售后管理系统&#xff0c;旨在助力企业销售售后全流程精细化、数字化管理&#xff0c;主要功能&#xff1a;客户、合同、工单、任务、报价、产品、库存、出纳、收费&#xff0c;适用于&#xff1a;服装鞋帽、化妆品、机械机…