ShardingSphere 5.x 系列【5】Spring Boot 3 集成并实现读写分离

news2024/11/24 12:59:43

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

本系列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 ,并指定YAML配置文件地址:

server:
  port: 8080
spring:
  datasource:
    # 配置 DataSource Driver
    driver-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.HikariDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.56.101:3306/test
    username: root
    password: "root"
  # 从库1
  read_ds_0:
    dataSourceClassName: com.zaxxer.hikari.HikariDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.56.101:3307/test
    username: root
    password: "root"
  # 从库2
  read_ds_1:
    dataSourceClassName: com.zaxxer.hikari.HikariDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.56.101:3308/test
    username: root
    password: "root"

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

# 规则配置
rules:
  # 读写分离配置
  - !READWRITE_SPLITTING
    dataSources: # 数据源
      readwrite_ds: # 读写分离逻辑数据源名称
        writeDataSourceName: write_ds # 写库数据源名称
        readDataSourceNames: # 读库数据源名称,多个从数据源用逗号分隔
          - read_ds_0
          - read_ds_1
        transactionalReadQueryStrategy: PRIMARY # 事务内读请求的路由策略,可选值:PRIMARY(路由至主库)、FIXED(同一事务内路由至固定数据源)、DYNAMIC(同一事务内路由至非固定数据源)。默认值:DYNAMIC
        loadBalancerName: read # 负载均衡自定义算法名称
    # 负载均衡算法
    loadBalancers:
      read:  # 自定义的算法名称
        type: RANDOM # 负载均衡算法类型
props:
  # 是否打印 SQL
  sql-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_SPLITTING
    dataSources: # 数据源
      readwrite_ds: # 读写分离逻辑数据源名称
        writeDataSourceName: write_ds # 写库数据源名称
        readDataSourceNames: # 读库数据源名称,多个从数据源用逗号分隔
          - read_ds_0
          - read_ds_1
        transactionalReadQueryStrategy: PRIMARY # 事务内读请求的路由策略,可选值:PRIMARY(路由至主库)、FIXED(同一事务内路由至固定数据源)、DYNAMIC(同一事务内路由至非固定数据源)。默认值:DYNAMIC
        loadBalancerName: read # 负载均衡自定义算法名称
    # 负载均衡算法
    loadBalancers:
      read:  # 自定义的算法名称
        type: ROUND_ROBIN # 负载均衡算法类型

4.2 随机

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

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

4.3 权重

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

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

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

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

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

相关文章

空气质量预测 | Matlab实现基于SVR支持向量机回归的空气质量预测模型

文章目录 效果一览文章概述源码设计参考资料效果一览 文章概述 政府机构使用空气质量指数 (AQI) 向公众传达当前空气污染程度或预测空气污染程度。 随着 AQI 的上升,公共卫生风险也会增加。 不同国家有自己的空气质量指数,对应不同国家的空气质量标准。 基于支持向量机(Su…

高速接口PCB布局指南(一)高速信号接口概述

高速接口PCB布局指南&#xff08;一&#xff09;高速信号接口概述 1.什么是高速信号接口&#xff1f;2.高速信号PCB设计概述2.1 概述2.2 关键信号 tips&#xff1a;资料主要来自网络&#xff0c;仅供学习使用。 1.什么是高速信号接口&#xff1f; 高速信号接口是指用于传输高…

jmeter-04创建请求

文章目录 一、发送请求-查看响应流程二、新建请求三、选择请求方式&#xff0c;填写url1.发送get请求当只有请求方式不一样的时候&#xff0c;参数都填写在参数栏里面&#xff0c;GET请求与POST请求的区别&#xff1f; 2.发送post请求2.1 application/x-www-form-urlencoded2.2…

二叉搜索树题目:二叉搜索树的最近公共祖先

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法一思路和算法代码复杂度分析 解法二思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;二叉搜索树的最近公共祖先 出处&#xff1a;235. 二叉搜索树的最近公共祖先 难度 3 级 题目描述 要求 给定一个…

Springboot集成ElasticSearch快速入门demo

一、ElasticSearch介绍 elasticsearch是构建在Apache Lucene上的使用Java语言开发的开源分布式搜素引擎。Lucene是一个开源的全文搜索引擎工具包&#xff0c;它仅是一个工具包而不是一个完整的工作引擎&#xff0c;并且只能被Java应用程序调用&#xff0c;elasticsearch基于RES…

云计算运营模式介绍

目录 一、云计算运营模式概述 1.1 概述 二、云计算服务角色 2.1 角色划分 2.1.1 云服务提供商 2.1.2 云服务消费者 2.1.3 云服务代理商 2.1.4 云计算审计员 2.1.5 云服务承运商 三、云计算责任模型 3.1 云计算服务模式与责任关系图 3.2 云计算服务模式与责任关系解析…

C++进阶--搜索二叉树

概念 搜索二叉树是一种特殊的二叉树&#xff0c;其具有以下特点&#xff1a; 1.对于每个结点&#xff0c;它的左子树中的所有节点的值都小于该节点的值&#xff0c;而右子树中的所有节点的值都大于该节点的值。 2.左子树和右子树都是搜索二叉树。 这个 特性使得搜索二叉树可…

计算机网络原理基础

目录 前言&#xff1a; 1.网络发展史 2.网络通信基础 2.1IP地址 2.1.1定义 2.1.2格式 2.2端口号 2.2.1定义 2.2.2格式 2.3协议 2.3.1定义 2.3.2作用 2.3.3分层 2.4五元组 2.4.1定义 2.4.2组成 3.TCP/IP五层网络模型 3.1模型概念 3.2模型构成 3.3网络分层对应…

06-Java适配器模式 ( Adapter Pattern )

原型模式 摘要实现范例 适配器模式&#xff08;Adapter Pattern&#xff09;是作为两个不兼容的接口之间的桥梁 适配器模式涉及到一个单一的类&#xff0c;该类负责加入独立的或不兼容的接口功能 举个真实的例子&#xff0c;读卡器是作为内存卡和笔记本之间的适配器。您将内…

机器学习逻辑回归模型训练与超参数调优 ##3

文章目录 [TOC]基于Kaggle电信用户流失案例数据&#xff08;可在官网进行下载&#xff09;逻辑回归模型训练逻辑回归的超参数调优 基于Kaggle电信用户流失案例数据&#xff08;可在官网进行下载&#xff09; 数据预处理部分可见&#xff1a; 机器学习数据预处理方法&#xff0…

layui

基于复杂结构的自定义模版相关介绍 我这里的接口给的格式数据 我这里搜索往返时候要显示成这样的 layui.use([table,form], function(){ var table layui.table; var form layui.form;// 渲染表格 table.render({ elem: #test-table-reload,toolbar: #toolbarDemo, …

【PPT密码】ppt设置的编辑密码,如何取消?

不知道大家是否了解PPT文件的编辑密码&#xff0c;首先ppt中没有限制编辑功能&#xff0c;设置为只读模式后仍然可以编辑文件&#xff0c;但其实有一种类似于限制编辑的加密方式。在我们打开PPT文件的时候会有密码输入框。 如果我们没有输入密码&#xff0c;以只读方式进入&…

每日一题——LeetCode1403.非递增顺序的最小子序列

方法一 个人方法&#xff1a; 按题目要求&#xff0c;尽可能先取出nums里最大的值&#xff0c;这样才能满足子序列尽可能短且元素之和最大 var minSubsequence function(nums) {nums.sort((a,b)>a-b)let sum1nums.reduce((a,b)>ab,0),sum20,res[]while(sum1>sum2){…

libevent源码解析--evbuffer_chain,evbuffer,bufferevent,bufferevent_private

1.概述 前面我们已经分析了event&#xff0c;event_callback&#xff0c;event_base及监听套接字处理。 有了event_base我们便可实现事件监控&#xff0c;事件分发处理。 有了监听套接字处理&#xff0c;我们便可实现服务端监听&#xff0c;通过accept得到服务端通信套接字。 …

Linux---信号

前言 到饭点了&#xff0c;我点了一份外卖&#xff0c;然后又开了一把网游&#xff0c;这个时候&#xff0c;我在打游戏的过程中&#xff0c;我始终记得外卖小哥会随时给我打电话&#xff0c;通知我我去取外卖&#xff0c;这个时候游戏还没有结束。我在打游戏的过程中需要把外…

【Boost】:阶段性测试和阶段性代码合集(五)

阶段性测试和阶段性代码合集 一.编写测试程序-server.cc二.一些问题三.完整源代码 在这里添加了一些打印信息&#xff0c;方便我们观察&#xff0c;由于比较分散就不一一列举&#xff0c;可以看下面的完整源代码。 一.编写测试程序-server.cc 1.原版 只是简单的测试&#xff0…

多输入多输出 | Matlab实现PSO-LSTM粒子群优化长短期记忆神经网络多输入多输出预测

多输入多输出 | Matlab实现PSO-LSTM粒子群优化长短期记忆神经网络多输入多输出预测 目录 多输入多输出 | Matlab实现PSO-LSTM粒子群优化长短期记忆神经网络多输入多输出预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab实现PSO-LSTM粒子群优化长短期记忆神经网络…

Java Arrays 的相关操作数组排序

Java Arrays 的相关操作数组排序 package com.zhong.arrays;import java.math.BigDecimal; import java.util.Arrays; import java.util.Comparator;public class ArraysDemo {public static void main(String[] args) {int[] arr {10, 20, 40, 30, 90, 60, 10, 30, 50};// A…

ReactNative实现文本渐变

我们直接上图&#xff0c;可以看到上面文本的效果&#xff0c;使用SVG实现 1.首先还是要引入react-native-svg库 2.使用该库下面的LinearGradient和Text 好&#xff0c;话不多说&#xff0c;我们看具体代码 <Svg width{422} height{30} viewBox{0 0 422 30}><Defs&…

以真机促创新!玻色量子联合中国运筹学会共商量子生态新模式

2024年1月29日&#xff0c;中国运筹学会算法软件与应用分会的一行领导莅临北京玻色量子科技有限公司&#xff08;以下简称“玻色量子”&#xff09;&#xff0c;参观了玻色量子及光量子计算机真机“天工量子大脑”、自建的十万颗粒洁净度光量子信息技术实验室&#x1f517;&…