尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

多租户后台管理系统怎么做才不失控:一次从单体改造成分布式集群的实践复盘

多租户后台管理系统怎么做才不失控:一次从单体改造成分布式集群的实践复盘 多租户后台管理系统怎么做才不失控一次从单体改造成分布式集群的实践复盘【免费下载链接】RuoYi-Vue-Plus多租户后台管理系统 重写RuoYi-Vue所有功能 集成 Sa-Token、Mybatis-Plus、WarmFlow、SpringDoc、Hutool、OSS 定期同步项目地址: https://gitcode.com/GitHub_Trending/ru/RuoYi-Vue-Plus去年我接手了一个基于 RuoYi-Vue 改造的后台管理系统客户的 SaaS 业务刚签下第三家租户。麻烦从那天开始租户 A 的订单数据出现在租户 B 的报表里排查了两天最后发现是手写的WHERE tenant_id ?漏掉了三处。这不是个例而是单体后台管理系统在多租户、分布式场景下的普遍失控方式。那之后我开始研究 RuoYi-Vue-Plus——一个面向分布式集群场景重写的多租户后台管理系统基于 Spring Boot 3 Vue 3集成了 Sa-Token、Mybatis-Plus、WarmFlow、SpringDoc 等组件。它不是把老代码打补丁而是把整套逻辑推倒重来。这篇文章记录我读它源码时的三个关键发现以及它如何避免我踩过的坑。别人的方案为什么不够好传统后台管理系统的租户隔离通常是约定大于机制开发者在每一条 SQL 后面手动追加tenant_id过滤条件。问题在于人能记住第一条 SQL记不住第一百条。MyBatis XML 里的关联查询、子查询、聚合统计只要漏掉一处数据就串了。更麻烦的是这类系统天生绑定单库单表自增主键在分库分表后必然冲突文件存本机意味着集群里每台机器各存各的Redis 客户端不支持集群模式定时任务用 Quartz 靠数据库锁抢执行权——分布式场景下每一步都是坑。RuoYi-Vue-Plus 的答案很直接把这些问题从开发者的责任变成框架的默认行为。拆解一租户隔离为什么能做得这么干净我在ruoyi-common-mybatis模块的MybatisPlusConfig里看到了关键一行——它注册了 MyBatis-Plus 的TenantLineInnerInterceptor多租户插件。这个拦截器的原理是所有 SQL 在执行前都要经过它它在解析阶段就把租户条件拼进去。开发者写SELECT * FROM sys_user到了数据库手里就变成了SELECT * FROM sys_user WHERE tenant_id ?。租户 ID 从哪来从 Sa-Token 登录态里取整个链路对业务代码完全透明。这带来的连锁好处是不会漏。过滤发生在 SQL 层不存在哪条查询忘了加条件的问题不限于单表。关联查询、分页、子查询同样被拦截隔离策略可调。某些表比如租户配置表本身通过注解排除在租户过滤之外。我在旧项目里花两周补漏的tenant_id在这里是开箱即用的默认行为。这就好比酒店给每位客人发独立房卡而不是靠客人自觉不串门。另一个细节值得注意主键策略被改成了雪花 ID并且用网卡信息绑定生成器防止集群环境下多个实例生成重复 ID。这是单体系统转向分布式最容易被忽略的一步——自增主键在合并数据时必撞车。拆解二一行注解背后的权限设计取舍权限这块老方案是 Spring Security配置繁琐角色与权限表达式能力弱。RuoYi-Vue-Plus 换成了 Sa-Token接口上直接挂注解SaCheckPermission(system:user:list) GetMapping(/list) public RPageResultSysUserVo list(SysUserBo bo) { return R.ok(sysUserService.selectPageUserList(bo)); }一行注解完成登录校验 权限校验。真正让我觉得它想清楚了的是注解支持AND、OR、权限 OR 角色这类复杂表达式——比如拥有审核权限或者属于财务角色这种真实业务场景不用再写一堆 if 分支。Sa-Token 本身的取舍是把 token 存在 Redis 里支持集群登录状态天然可共享、可踢人、可续期。对比单体时代每台机器各自维护 session的做法这是分布式系统的基础设施级别差异。拆解三登录接口是怎么做到支持五种认证方式的看AuthController的登录方法时我发现了一个很有意思的设计——策略模式被玩得很干净LoginVo loginVo IAuthStrategy.login(body, client, grantType);IAuthStrategy的静态方法里grantType直接拼进 Bean 名称去容器里找实现类String beanName grantType IAuthStrategy.BASE_NAME; // 如 passwordAuthStrategy if (!SpringUtils.containsBean(beanName)) { throw new ServiceException(授权类型不正确!); } IAuthStrategy instance SpringUtils.getBean(beanName);于是密码登录、短信登录、邮箱登录、小程序登录、第三方社交登录各自是实现类互不干扰。想加一种新的认证方式写一个类继承IAuthStrategy用Service(xxxAuthStrategy)注册完事。我截取密码登录的核心片段看它做了哪些事boolean captchaEnabled captchaProperties.getEnable(); if (captchaEnabled) { validateCaptcha(username, code, uuid); // 1. 验证码可全局开关 } SysUserVo user loadUserByUsername(username); loginService.checkLogin(LoginType.PASSWORD, username, () - !BCrypt.checkpw(password, user.getPassword())); // 2. BCrypt 校验 失败计数 LoginUser loginUser loginService.buildLoginUser(user); loginUser.setClientKey(client.getClientKey()); SaLoginParameter model IAuthStrategy.buildLoginParameter(client); LoginHelper.login(loginUser, model); // 3. 按客户端配置生成 token注意loginService.checkLogin传的是一个 lambda——密码是否正确由调用方决定登录失败次数统计、锁定策略则由框架统一处理。每个客户端PC 端、小程序端还能独立配置 token 有效期、活跃超时、IP 白名单这是 OAuth 风格的客户端管理思路老 RuoYi 里是没有的。对照表改造成本到底省在哪能力单体后台管理系统的做法RuoYi-Vue-Plus 的做法我感受到的差异租户隔离手写tenant_id过滤MyBatis-Plus 插件自动拼接从可能漏变成不会漏主键数据库自增雪花 ID分库分表后不再冲突权限Spring Security 配置Sa-Token 注解复杂表达式一行搞定登录方式写死账号密码策略模式按需注册加一种认证约半小时数据源单数据源dynamic-datasource 异构切换MySQL/Oracle/PG 可并存任务调度Quartz 数据库锁SnailJob 分布式调度集群下不再抢锁文件存储本机磁盘MinIO / S3 协议云存储消除单点支持集群接口文档Springfox 写注解SpringDoc 读 javadoc 注释注释写得好就有文档一次带代码的实操从零跑起来如果你也想试试流程比我想象的短git clone https://gitcode.com/GitHub_Trending/ru/RuoYi-Vue-Plus cd RuoYi-Vue-Plus建库并导入script/sql/ry_vue.sql根目录还有ry_workflow.sql、ry_job.sql、ry_ai.sql按需导入改ruoyi-admin/src/main/resources/application.yml里的数据源与 Redis 连接mvn clean package -DskipTests跑ruoyi-admin模块即可。项目自带 Docker 编排script/docker/docker-compose.ymlMySQL、Redis 一条命令起齐。上生产前记得把application.yml里的默认密码、profile环境标识换成prod。几个避坑提醒多租户插件不等于安全边界。插件只管 SQL 层接口层面的越权仍需配合数据权限注解两者叠加才完整切换数据库方言要测关联查询。虽然支持 MySQL / Oracle / PostgreSQL / SQLServer但分页、排序的方言差异建议在目标库上跑一遍全量测试生产环境别开devprofile。pom.xml里的dev是默认激活的部署时务必显式指定prod否则监控口令等敏感配置会以默认值生效新增业务表时想清楚是否参与租户隔离。全局配置表要排除业务数据表要包含插件给了你选择权但用不用得对取决于设计。行动清单如果你正面临和我当时类似的处境——单体后台要往多租户、分布式方向走可以先做这三件事用它的代码生成器ruoyi-gen模块生成一张表的完整 CRUD感受一下设计好表结构前后端代码五分钟出齐是什么体验打开MybatisPlusConfig把每个拦截器的官方文档注释读一遍这比看十篇博客都管用对照上面那张表把你现有系统的薄弱项列出来评估迁移成本——大多数情况下迁移到 RuoYi-Vue-Plus 比在旧代码上缝缝补补更省钱。对我而言最大的收获不是它有多少现成功能而是它示范了一件事框架层面的默认正确胜过开发者层面的一万次小心。租户隔离、主键生成、登录态共享这些分布式系统的硬骨头交给框架去兜底人才能把精力放回真正的业务上。【免费下载链接】RuoYi-Vue-Plus多租户后台管理系统 重写RuoYi-Vue所有功能 集成 Sa-Token、Mybatis-Plus、WarmFlow、SpringDoc、Hutool、OSS 定期同步项目地址: https://gitcode.com/GitHub_Trending/ru/RuoYi-Vue-Plus创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表