Spring Boot 多租户架构实现:基于上下文自动传递的独立资源隔离方案

一、核心设计思想
通过线程上下文自动传递租户ID,结合动态数据源路由和中间件连接工厂,实现MySQL、Redis、RocketMQ的完全自动化资源隔离。关键设计如下:

Client Gateway TenantContext MySQL Redis RocketMQ 携带X-Tenant-ID请求 解析并设置租户ID 自动路由到tenantA数据源 自动选择tenantA连接池 自动绑定tenantA Topic 释放连接 关闭连接 移除监听 Client Gateway TenantContext MySQL Redis RocketMQ

二、关键实现方案

  1. 租户上下文管理(核心)
public class TenantContext {// 使用TransmittableThreadLocal支持异步传递private static final TransmittableThreadLocal<String> CONTEXT = new TransmittableThreadLocal<>();public static void set(String tenantId) {CONTEXT.set(tenantId);DynamicDataSourceContextHolder.push(tenantId); // 同步MySQL上下文}public static String get() {return CONTEXT.get();}public static void clear() {CONTEXT.remove();DynamicDataSourceContextHolder.poll(); // 清理MySQL上下文}
}
  1. MySQL动态数据源配置
@Configuration
@MapperScan(basePackages = "com.example.mapper")
public class DataSourceConfig {@Bean@ConfigurationProperties(prefix = "spring.datasource.master")public DataSource masterDataSource() {return DataSourceBuilder.create().build();}@Bean@ConfigurationProperties(prefix = "spring.datasource.tenantA")public DataSource tenantADatasource() {return DataSourceBuilder.create().build();}@Bean@ConfigurationProperties(prefix = "spring.datasource.tenantB")public DataSource tenantBDatasource() {return DataSourceBuilder.create().build();}@Beanpublic DataSource routingDataSource(@Qualifier("masterDataSource") DataSource master,@Qualifier("tenantADatasource") DataSource tenantA,@Qualifier("tenantBDatasource") DataSource tenantB) {Map<Object, Object> targetDataSources = new HashMap<>();targetDataSources.put("tenantA", tenantA);targetDataSources.put("tenantB", tenantB);DynamicRoutingDataSource routingDataSource = new DynamicRoutingDataSource();routingDataSource.setDefaultTargetDataSource(master);routingDataSource.setTargetDataSources(targetDataSources);return routingDataSource;}
}public class DynamicRoutingDataSource extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {return DynamicDataSourceContextHolder.getDataSourceKey();}
}
  1. Redis连接工厂隔离
@Configuration
public class RedisConfig {@Beanpublic RedisConnectionFactory tenantARedisFactory() {RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();config.setDatabase(1); // 租户A专用DBreturn new LettuceConnectionFactory(config);}@Beanpublic RedisConnectionFactory tenantBRedisFactory() {RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();config.setDatabase(2); // 租户B专用DBreturn new LettuceConnectionFactory(config);}@Beanpublic RedisTemplate<String, Object> redisTemplate(@Qualifier("tenantARedisFactory") RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(factory);template.setKeySerializer(new TenantAwareStringRedisSerializer());return template;}
}public class TenantAwareStringRedisSerializer implements StringRedisSerializer {@Overridepublic String serialize(String string) {String tenantId = TenantContext.get();return (tenantId == null) ? string : tenantId + ":" + string;}
}
  1. RocketMQ生产者/消费者自动绑定
@Configuration
public class RocketMQConfig {@Beanpublic DefaultMQProducer tenantProducer() throws MQClientException {DefaultMQProducer producer = new DefaultMQProducer("tenant_producer");producer.setNamesrvAddr("127.0.0.1:9876");producer.start();return producer;}@Beanpublic RocketMQListener<String> tenantListener() {return new TenantAwareListener();}
}public class TenantAwareListener implements RocketMQListener<String> {@Overridepublic void onMessage(String message) {String tenantId = TenantContext.get();// 自动路由到租户专属TopicString targetTopic = "topic_" + tenantId;// 处理消息...}
}

三、自动化上下文传播

  1. 请求拦截器
@Component
public class TenantInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {String tenantId = request.getHeader("X-Tenant-ID");TenantContext.set(tenantId);return true;}@Overridepublic void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) {TenantContext.clear();}
}
  1. 异步任务支持
@EnableAsync
@Configuration
public class AsyncConfig implements AsyncConfigurer {@Overridepublic Executor getAsyncExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setTaskDecorator(new ContextCopyingDecorator());executor.initialize();return executor;}private static class ContextCopyingDecorator implements TaskDecorator {@Overridepublic Runnable decorate(Runnable runnable) {String tenantId = TenantContext.get();return () -> {try {TenantContext.set(tenantId);runnable.run();} finally {TenantContext.clear();}};}}
}

四、完整工作流程

  1. 请求入口
    网关拦截请求 → 解析X-Tenant-ID → 设置到TenantContext

  2. 数据访问层

    @Service
    public class OrderService {@Autowiredprivate OrderMapper orderMapper;public Order getOrder(Long id) {// 自动路由到当前租户的数据源return orderMapper.selectById(id);}
    }
    
  3. Redis操作

    @Service
    public class CacheService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;public void setValue(String key, Object value) {// 自动添加租户前缀redisTemplate.opsForValue().set(key, value);}
    }
    
  4. 消息发送

    @Service
    public class MessageService {@Autowiredprivate DefaultMQProducer producer;public void sendOrderCreated(Order order) {Message msg = new Message("order_created", order.toJson());producer.send(msg); // 自动绑定租户Topic}
    }
    

五、技术优势对比

方案上下文传递方式中间件隔离级别代码侵入性线程安全
手动切换显式代码调用应用层需要处理
本方案线程上下文自动传播物理隔离原生支持
动态注解AOP切面逻辑隔离需要配置

六、生产环境优化点

  1. 连接池监控

    spring:datasource:tenantA:hikari:maximum-pool-size: 20leak-detection-threshold: 30000
    
  2. RocketMQ消费者隔离

    @RocketMQMessageListener(topic = "tenant_#{tenantId}_topic",consumerGroup = "tenant_#{tenantId}_group"
    )
    public class TenantConsumer implements RocketMQListener<String> {// 自动注入当前租户的Consumer
    }
    
  3. Redis集群支持

    @Bean
    public RedisClusterConfiguration tenantARedisCluster() {RedisClusterConfiguration config = new RedisClusterConfiguration();config.setClusterNodes(Arrays.asList("127.0.0.1:7001", "127.0.0.1:7002"));config.setPassword("tenantA@2024");return config;
    }
    

通过本方案,可实现完全自动化的多租户资源隔离,核心优势在于:

  1. 零代码侵入:通过上下文自动传播实现资源隔离
  2. 物理级隔离:每个租户拥有独立数据库/消息队列/缓存集群
  3. 动态扩展:新增租户只需添加配置,无需修改代码

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

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

相关文章

参与开发的注意事项

1.开发期间&#xff0c;不要擅自修改架构的内容 使用技术官发的项目文件夹来开发&#xff0c;而不是自己建立项目&#xff0c; 否则会导致环境不统一 架构内容&#xff1a;&#xff08;不能更改&#xff09; 1.类型定义&#xff0c;全局变量声明 2.函数申明&#xff08;函数名称…

产业互联网+三融战略:重构企业增长密码

产业互联网时代&#xff1a;用"三融"重构企业增长飞轮 在产业互联网浪潮下&#xff0c;企业面临资源分散、资金短缺、人才难聚的三重挑战。本文提出的"融人、融资、融资源"顶层设计&#xff0c;正为新时代企业构建增长新引擎。 一、三级合伙人体系&#x…

【JavaScript异步编程终极指南】从回调地狱到Async/Await的实战突围

目录 &#x1f30d; 前言&#xff1a;技术背景与价值&#x1f494; 当前技术痛点&#x1f6e0; 解决方案概述&#x1f465; 目标读者说明&#x1f50d; 一、技术原理剖析&#x1f9e0; 核心作用讲解&#x1f9e9; 关键技术模块说明⚖️ 技术选型对比 &#x1f4bb; 二、实战演示…

国标GB28181设备管理软件EasyGBS视频监控系统打造工厂可视化监管场景解决方案

一、引言​ 随着工厂规模扩大、生产流程复杂化&#xff0c;传统管理模式已难以满足精细化运营需求。当前部分工厂视频监控系统存在设备协议不兼容、功能分散等问题。EasyGBS视频监控系统基于GB28181标准协议&#xff0c;以高兼容性架构实现设备统一接入&#xff0c;集成视频全…

# 终端执行 java -jar example.jar 时(example.jar为项目jar包)报错:“没有主清单属性” 的解决方法

终端执行 java -jar example.jar 时&#xff08;example.jar为项目jar包&#xff09;报错&#xff1a;“没有主清单属性” 的解决方法 在Java中&#xff0c;一个JAR文件必须包含一个主清单属性&#xff08;Main-Class属性&#xff09;才能在命令行中直接运行。如果你在尝试运行…

使用 mutt 发送邮件:Linux 下轻量高效的命令行邮件工具

文章目录 一、安装 mutt二、配置 .muttrc三、发送一封简单邮件四、发送给多个收件人五、发送附件六、临时设置发件人七、脚本示例&#xff1a;八.结语 在 Linux 或类 Unix 系统中&#xff0c;mutt 是一款经典且强大的命令行邮件客户端&#xff08;MUA&#xff0c;邮件用户代理&…

OceanBase 开发者大会,拥抱 Data*AI 战略,构建 AI 数据底座

5 月 17 号以“当 SQL 遇见 AI”为主题的 OceanBase 开发者大会在广州举行&#xff0c;因为行程的原因未能现场参会&#xff0c;仍然通过视频直播观看了全部的演讲。总体来说&#xff0c;这届大会既有对未来数据库演进方向的展望&#xff0c;也有 OceanBase 新产品的发布&#…

为 Spring Boot 应用程序构建 CI/CD 流水线

为 Spring Boot 应用程序创建构建/部署流水线涉及多个步骤,而 Jenkins 可以作为强大的工具来自动化这些流程。在本教程中,我们将指导您为托管在 GitHub 上的 Spring Boot 应用程序设置流水线,使用 Jenkins 构建该应用程序,并将其部署到 Amazon Elastic Kubernetes Service …

BI是什么意思?一文讲清BI的概念与应用!

目录 一、BI 是什么意思 1. BI 的定义 2. BI 的发展历程 3. BI 的核心组件 二、BI 的应用场景 1. 销售与市场营销 2. 财务管理 ​编辑3. 人力资源管理 4. 生产与运营管理 ​编辑三、选择合适的 BI 工具 1. 考虑企业的需求和规模 2. 评估工具的功能和性能 3. 关注工…

磁盘分区与挂载——笔记

1.磁盘分区 磁盘分区是将物理磁盘划分为多个逻辑区域的过程。每个分区可视为独立的存储单元&#xff0c;拥有独立的文件系统&#xff0c;可安装不同操作系统或存放不同类型数据。例如&#xff0c;将硬盘分为系统盘&#xff08;存放操作系统&#xff09;、数据盘&#xff08;存…

如何让 Google 收录 Github Pages 个人博客

版权归作者所有&#xff0c;如有转发&#xff0c;请注明文章出处&#xff1a;https://cyrus-studio.github.io/blog/ 如何确认自己的网站有没有被 google 收录 假设网址是&#xff1a;https://cyrus-studio.github.io/blog 搜索&#xff1a;site:https://cyrus-studio.github…

HarmonyOS Next 关键资产的解释

关键资产的安全存储与管理&#xff1a;HarmonyOS Asset Store Kit 深度解析 一、关键资产的定义与重要性 关键资产&#xff08;Critical Asset&#xff09;是指应用运行过程中涉及的短敏感数据&#xff0c;包括但不限于用户密码、身份令牌&#xff08;Token&#xff09;、银行…

机器学习(12)——LGBM(1)

文章目录 LightGBM算法详解1. 算法背景2. 核心创新2.1 基于直方图的决策树算法2.2 单边梯度采样(GOSS)2.3 互斥特征捆绑(EFB) 3. 算法细节3.1 树生长策略3.2 特征并行与数据并行3.3 类别特征处理 4. 关键参数说明4.1 核心参数4.2 控制速度参数4.3 控制过拟合参数 5. 与XGBoost对…

网络安全-等级保护(等保) 2-7-3 GB/T 25058—2019 第7章 安全设计与实施

############################################################################### 对于安全厂家而言&#xff0c;最关心的内容在本章节&#xff0c;根据已确定的安全总体方案&#xff0c;完成技术措施和管理措施的详细设计和实施&#xff0c;包含具体的安全产品和管理要求。…

PHP-FPM 调优配置建议

1、动态模式 pm dynamic; 最大子进程数&#xff08;根据服务器内存调整&#xff09; pm.max_children 100 //每个PHP-FPM进程大约占用30-50MB内存(ThinkPHP框架本身有一定内存开销)安全值&#xff1a;8GB内存 / 50MB ≈ 160&#xff0c;保守设置为100 ; 启动时创建的进程数&…

DDoS防护实战——从基础配置到高防IP部署

一、基础防护&#xff1a;服务器与网络层加固 Linux内核优化&#xff1a; 调整TCP协议栈参数&#xff0c;缓解SYN Flood攻击&#xff1a; # 启用SYN Cookie并减少超时时间 echo 1 > /proc/sys/net/ipv4/tcp_syncookies echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout…

使用 NGINX 的 `ngx_http_secure_link_module` 模块保护资源链接

一、模块简介 版本&#xff1a;自 NGINX 0.7.18 起引入 功能&#xff1a; 签名校验&#xff1a;对请求 URI 中的签名进行校验&#xff0c;保证链接未经篡改。时效控制&#xff1a;根据请求中携带的过期时间&#xff0c;判断链接是否仍在有效期。 启用方式&#xff1a;编译 NG…

前端三剑客之HTML

前端HTML 一、HTML简介 1.什么是html HTML的全称为超文本标记语言(HTML How To Make Love HyperText Markup Language )&#xff0c;是一种标记语言。它包括一系列标签&#xff0c;通过这些标签可以将网络上的文档格式统一&#xff0c;使分散的Internet资源连接为一个逻辑整…

网络安全-等级保护(等保) 2-0 等级保护制度现行技术标准

################################################################################ 第二章&#xff1a;现行等保标准要求&#xff0c;通过表格方式详细拆分了等保的相关要求。 GB 17859-1999 计算机信息系统 安全保护等级划分准则【现行】 GB/T22240-2020 《信息安全技术 网…

目标检测 LW-DETR(2024)详细解读

文章目录 整体架构 LW-DETR全称Light-Weight DETR&#xff0c;是百度团队提出的第二代面向实时检测算法&#xff0c;比yolo v8的速度和精度更好 整体架构 LW-DETR 由一个ViT编码器&#xff08;Vision Transformer Encoder&#xff09;、一个投影器&#xff08;Projector&#…