介绍下SpringBoot在分布式架构中,如何实现读写分离

在分布式架构中,Spring Boot 可以通过多种方式实现读写分离,以提升系统性能和扩展性。以下是常见的实现方法:

1. 使用多数据源

通过配置多个数据源,将读操作和写操作分别路由到不同的数据库实例。

实现步骤:
  1. 配置多数据源
    application.ymlapplication.properties 中配置主从数据源。

    spring:datasource:master:url: jdbc:mysql://master-host:3306/dbusername: rootpassword: rootslave:url: jdbc:mysql://slave-host:3306/dbusername: rootpassword: root
    
  2. 创建数据源配置类
    使用 @Configuration@Bean 注解配置主从数据源。

    @Configuration
    public class DataSourceConfig {@Bean(name = "masterDataSource")@ConfigurationProperties(prefix = "spring.datasource.master")public DataSource masterDataSource() {return DataSourceBuilder.create().build();}@Bean(name = "slaveDataSource")@ConfigurationProperties(prefix = "spring.datasource.slave")public DataSource slaveDataSource() {return DataSourceBuilder.create().build();}@Primary@Bean(name = "routingDataSource")public DataSource routingDataSource(@Qualifier("masterDataSource") DataSource masterDataSource,@Qualifier("slaveDataSource") DataSource slaveDataSource) {Map<Object, Object> targetDataSources = new HashMap<>();targetDataSources.put("master", masterDataSource);targetDataSources.put("slave", slaveDataSource);AbstractRoutingDataSource routingDataSource = new AbstractRoutingDataSource() {@Overrideprotected Object determineCurrentLookupKey() {return DataSourceContextHolder.getDataSourceKey();}};routingDataSource.setDefaultTargetDataSource(masterDataSource);routingDataSource.setTargetDataSources(targetDataSources);return routingDataSource;}
    }
    
  3. 数据源上下文管理
    使用 ThreadLocal 管理当前线程的数据源。

    public class DataSourceContextHolder {private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();public static void setDataSourceKey(String key) {contextHolder.set(key);}public static String getDataSourceKey() {return contextHolder.get();}public static void clearDataSourceKey() {contextHolder.remove();}
    }
    
  4. AOP 切面实现数据源切换
    通过 AOP 在方法执行前切换数据源。

    @Aspect
    @Component
    public class DataSourceAspect {@Before("@annotation(com.example.annotation.Master)")public void setMasterDataSource() {DataSourceContextHolder.setDataSourceKey("master");}@Before("@annotation(com.example.annotation.Slave)")public void setSlaveDataSource() {DataSourceContextHolder.setDataSourceKey("slave");}@After("@annotation(com.example.annotation.Master) || @annotation(com.example.annotation.Slave)")public void clearDataSource() {DataSourceContextHolder.clearDataSourceKey();}
    }
    
  5. 自定义注解
    定义 @Master@Slave 注解,用于标记方法使用主库或从库。

    @Target({ElementType.METHOD, ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Master {
    }@Target({ElementType.METHOD, ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Slave {
    }
    
  6. 在 Service 层使用注解
    在 Service 层方法上使用 @Master@Slave 注解。

    @Service
    public class UserService {@Autowiredprivate UserMapper userMapper;@Masterpublic void addUser(User user) {userMapper.insert(user);}@Slavepublic User getUserById(Long id) {return userMapper.selectById(id);}
    }
    

2. 使用中间件

借助数据库中间件(如 MyCAT、ShardingSphere)自动实现读写分离,减少应用层代码的复杂性。

实现步骤:
  1. 配置中间件
    在中间件中配置主从数据库,并设置读写分离规则。

  2. 应用连接中间件
    在 Spring Boot 中配置数据源连接中间件,而非直接连接数据库。

3. 使用 Spring Cloud 组件

在微服务架构中,结合 Spring Cloud 组件(如 Spring Cloud Gateway、Spring Cloud Config)动态管理数据源。

实现步骤:
  1. 配置中心管理数据源
    使用 Spring Cloud Config 动态更新数据源配置。

  2. 服务网关路由
    通过 Spring Cloud Gateway 实现请求路由,将读写请求分发到不同服务实例。

总结

Spring Boot 实现读写分离的常见方法包括多数据源配置、中间件和 Spring Cloud 组件。多数据源配置适合中小型项目,中间件适合大型分布式系统,Spring Cloud 组件则适合微服务架构。选择合适的方法取决于具体需求和系统规模。

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

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

相关文章

摄像头动捕:摄像头+AI精准捕捉动作

在科技蓬勃发展的当下&#xff0c;动作捕捉技术已从最初的小众应用逐渐走进大众视野&#xff0c;广泛渗透到众多领域。其中&#xff0c;摄像头动捕&#xff0c;也就是无穿戴动作捕捉系统&#xff0c;以其独特的技术优势和创新应用&#xff0c;正悄然改变着人们对动作捕捉的认知…

Unity3D Shader 简析:变体与缓存详解

引言 在 Unity3D 中&#xff0c;Shader 是渲染管线的核心部分&#xff0c;负责控制物体的外观和材质表现。Shader 的变体&#xff08;Variants&#xff09;和缓存机制是优化渲染性能的关键。本文将深入探讨 Unity3D 中 Shader 变体的概念、缓存机制以及如何通过代码实现和管理…

机器学习 - 词袋模型(Bag of Words)实现文本情感分类的详细示例

为了简单直观的理解模型训练&#xff0c;我这里搜集了两个简单的实现文本情感分类的例子&#xff0c;第一个例子基于朴素贝叶斯分类器&#xff0c;第二个例子基于逻辑回归&#xff0c;通过这两个例子&#xff0c;掌握词袋模型&#xff08;Bag of Words&#xff09;实现文本情感…

Java JVM(Java Virtual Machine)解析

Java Virtual Machine&#xff08;JVM&#xff09;是Java平台的核心组成部分&#xff0c;它负责执行Java字节码&#xff0c;并提供了一个运行时环境。本文将深入探讨JVM的工作原理、组成部分以及其在Java开发中的重要性。 一、JVM的基本概念 JVM是一个虚拟的计算机&#xff0…

Miniforge —— 轻量化的 conda 解决方案

引言 在日常使用中&#xff0c;我们常常使用 Anaconda 或 Miniconda 来管理 Python 环境和包。但由于 Anaconda/Miniconda 属于商业产品&#xff0c;当企业规模超过一定人数时就会涉及付费问题。相比之下&#xff0c;Miniforge 是由社区主导维护的一个完全免费的替代方案&…

【CS61A 2024秋】Python入门课,全过程记录P7(Week13 Macros至完结)【完结撒花!】

文章目录 关于新的问题更好的解决方案Week13Mon Macros阅读材料Lab 11: Programs as Data, MacrosQ1: WWSD: QuasiquoteQ2: If ProgramQ3: Exponential PowersQ4: Repeat Wed SQL阅读材料Disc 11: MacrosQ1: Mystery MacroQ2: Multiple AssignmentQ3: Switch Optional Contest:…

《Python百炼成仙》11-20章(不定时跟新)

第十一章 条件渡劫if-else问心 武当金顶的云海翻涌着二进制雪暴&#xff0c;七十二峰化作擎天而立的布尔冰柱。叶军踩着《周易》残页跃上紫霄宫檐角&#xff0c;看见薛香被冰封在水晶般的条件表达式中心&#xff1a; if 道心澄澈:破妄剑意 100else:心魔熵值 * 2楔子三元寒渊 …

Tomcat添加到Windows系统服务中,服务名称带空格

要将Tomcat添加到Windows系统服务中&#xff0c;可以通过Tomcat安装目录中“\bin\service.bat”来完成&#xff0c;如果目录中没有service.bat&#xff0c;则需要使用其它方法。 打到CMD命令行窗口&#xff0c;通过cd命令跳转到Tomcat安装目录的“\bin\”目录&#xff0c;然后执…

WPS接入DeepSeek模型

1.wps 下载安装 WPS-支持多人在线协作编辑Word、Excel和PPT文档_WPS官方网站 &#xff08;最好是安装最新的wps&#xff09; 2.offieceAi工具下载安装 软件下载 | OfficeAI助手 下载后安装下载下来的两个工具。安装路径可以自行修改 3.打开WPS,点击文件-》 选项-》信任中心 勾…

数据结构与算法之数组: LeetCode 905. 按奇偶排序数组 (Ts版)

按奇偶排序数组 https://leetcode.cn/problems/sort-array-by-parity/description/ 描述 给你一个整数数组 nums&#xff0c;将 nums 中的的所有偶数元素移动到数组的前面&#xff0c;后跟所有奇数元素。 返回满足此条件的 任一数组 作为答案。 示例 1 输入&#xff1a;n…

Qt简单使用正则表达式

正则表达式 用于数据处理&#xff0c;数据查询&#xff0c;数据格式验证&#xff0c;替换文本&#xff0c;提取字串&#xff0c;相比str函数正则技术&#xff0c;开销小 在Qt简单使用正则表达式 在qt中使用类QRegExp类使用正则表达式 需要使用头文件 #include <QRegExp>…

LabVIEW 用户界面设计基础原则

在设计LabVIEW VI的用户界面时&#xff0c;前面板的外观和布局至关重要。良好的设计不仅提升用户体验&#xff0c;还能提升界面的易用性和可操作性。以下是设计用户界面时的一些关键要点&#xff1a; 1. 前面板设计原则 交互性&#xff1a;组合相关的输入控件和显示控件&#x…

使用开源项目xxl-cache构建多级缓存

xxl-cache简介 官网地址&#xff1a;https://www.xuxueli.com/xxl-cache/ 概述 XXL-CACHE 是一个 多级缓存框架&#xff0c;高效组合本地缓存和分布式缓存(RedisCaffeine)&#xff0c;支持“多级缓存、一致性保障、TTL、Category隔离、防穿透”等能力&#xff1b;拥有“高性…

C++ 设计模式-适配器模式

适配器模式示例,包括多电压支持、类适配器实现、安全校验等功能: #include <iostream> #include <memory> #include <stdexcept>// 抽象目标接口:通用电源接口 class PowerOutlet {public:virtual ~PowerOutlet() = default;virtual int outputPower() c…

【Java八股文】02-Java集合面试篇

【Java八股文】02-Java集合面试篇 概念数组与集合区别常用集合Java中的线程安全的集合是什么&#xff1f;Collections和Collection的区别 Listjava中list的几种实现把ArrayList变成线程安全的有哪些方法&#xff1f;CopyOnWriteArrayList是如何保证线程安全的&#xff1f; Mapj…

tenda路由器WriteFacMac存在远程命令执行漏洞(CVE-2024-10697)

一、漏洞简介 tenda路由器WriteFacMac存在远程命令执行漏洞 二、漏洞影响 tenda路由器三、网络测绘&#xff1a; fofa: title"Tenda | LOGIN"四、复现过程 POC 1 GET /goform/WriteFacMac?macls%20%3E/webroot/1.txt HTTP/1.1 Accept: text/html,application/…

C语言中字符与字符串的区别?

在 C 语言中&#xff0c;字符&#xff08;Character&#xff09;和字符串&#xff08;String&#xff09;是两个不同的概念&#xff0c;它们在定义、存储、操作等方面都存在明显的区别&#xff0c;下面为你详细介绍&#xff1a; 定义与表示 字符 &#xff08;1&#xff09;字…

mapbox进阶,添加绘图扩展插件,裁剪线

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️MapboxDraw 绘图控件二、🍀添加绘图扩…

react redux用法学习

参考资料&#xff1a; https://www.bilibili.com/video/BV1ZB4y1Z7o8 https://cn.redux.js.org/tutorials/essentials/part-5-async-logic AI工具&#xff1a;deepseek&#xff0c;通义灵码 第一天 安装相关依赖&#xff1a; 使用redux的中间件&#xff1a; npm i react-redu…

crontab制定任务计划删除超过5天以上的文件

文章目录 1.find命令的基本用法2.编写脚本3.制定任务计划4.制定任务计划后一定要重启一下crontab服务1.find命令的基本用法 #查询/data/docker/overlay2/目录下的host.access.log文件 find /data/docker/overlay2/ -path */log/nginx/host.access.log -print #删除/root/da…