基于RuoYi-Cloud-Plus 框架的微服务学习教程
RuoYi-Cloud-Plus 微服务学习教程面向有 SpringBoot 基础的 Java 开发者,基于项目真实代码,从零掌握微服务架构标签:共 7 课 · 基于 v2.4.1 源码 · 含实操测试课程目录从单体到微服务的思维转变 — 理解为什么要拆服务服务注册与发现 Nacos — 服务之间怎么找到对方API 网关 Gateway — 统一入口、路由、鉴权、跨域服务间通信 Feign — 远程调用与降级兜底统一配置中心 — 配置集中管理与动态刷新分布式认证 Sa-Token — 微服务下登录状态共享公共模块设计与进阶 — 30+ 模块复用、多租户、缓存第一课:从单体到微服务的思维转变对应代码:pom.xml + 各服务 Application 启动类1.1 你熟悉的世界:SpringBoot 单体你熟悉的 SpringBoot 项目结构:// 单体应用:一个进程、一个端口、一个数据库 my-project/ src/main/java/com/example/ controller/ // 所有接口 service/ // 所有业务逻辑 mapper/ // 所有数据库操作 Application.java // 一个启动类 src/main/resources/ application.yml // 一个配置文件管所有 pom.xml // 一个 pom 管所有依赖方法之间直接调用,Controller → Service → Mapper,都在同一个 JVM 里。1.2 微服务的世界:拆成多个独立应用看这个项目的顶层pom.xml,有 7 个子模块:// 微服务:多个进程、多个端口、多个数据库 ruoyi-cloud-plus/ ├── ruoyi-gateway // 网关(端口 8080) ├── ruoyi-auth // 认证服务(端口 9210) ├── ruoyi-modules/ │ ├── ruoyi-system // 系统服务(端口 9201) │ ├── ruoyi-resource // 资源服务(端口 9204) │ ├── ruoyi-workflow // 工作流(端口 9205) │ ├── ruoyi-gen // 代码生成(端口 9202) │ └── ruoyi-job // 定时任务(端口 9203) ├── ruoyi-api // 服务间调用接口定义(不是独立进程) ├── ruoyi-common // 30+ 公共模块(不是独立进程) └── ruoyi-visual/ // 基础设施 ├── ruoyi-nacos // 注册中心(端口 8848) └── ...1.3 核心认知:每个微服务仍然是一个 SpringBoot 应用看RuoYiSystemApplication.java:@SpringBootApplicationpublicclassRuoYiSystemApplication{publicstaticvoidmain(String[]args){SpringApplicationapplication=newSpringApplication(RuoYiSystemApplication.class);application.run(args);}}跟单体应用的启动类一模一样。微服务不是推翻你学的东西,而是在 SpringBoot 基础上加了三样东西:你会的(单体)微服务新增的对应本项目代码Controller/Service/Mapper服务注册(告诉别人我存在)application.yml的nacos.discovery方法之间直接调用远程调用(Feign)ruoyi-api的@FeignClient一个 yml 管所有配置集中管理(Nacos)spring.config.import浏览器直接访问 Controller统一入口网关(Gateway)ruoyi-gateway模块1.4 一个微服务的配置长什么样看ruoyi-system/src/main/resources/application.yml:server:port:9201# 这个服务跑在 9201 端口spring:application:name:ruoyi-system# 服务名,别的服务靠这个名字找到它cloud:nacos:server-addr:127.0.0.1:8848# 注册中心地址discovery:group:DEFAULT_GROUP# 注册到哪个组config:import:# 从 Nacos 拉哪些配置文件-optional:nacos:application-common.yml-optional:nacos:datasource.yml-optional:nacos:ruoyi-system.yml本地 yml 只保留最基本的:我叫什么名字、我跑在哪个端口、我去哪里注册、我去哪里拉配置。真正的业务配置全在 Nacos。1.5 网关:前端的唯一入口前端请求 /system/user/list │ ▼ 网关 Gateway (:8080) │ 匹配路由规则 /system/** → ruoyi-system │ 去掉第一层前缀 → /user/list ▼ ruoyi-system 服务收到 /user/list所有前端请求先到网关,网关根据 URL 前缀决定转发给哪个服务。前端不需要知道后面有几个服务。[!note] 本课小结微服务= 把一个大应用拆成多个独立的小应用,每个独立部署、独立数据库每个微服务仍然是一个 SpringBoot 应用,启动类完全一样微服务比单体多了三样东西:服务注册、远程调用、统一配置前端只跟网关通信,网关负责路由到具体服务[!tip] 实操测试打开项目根目录pom.xml,找到modules标签,数一数有几个子模块分别打开RuoYiGatewayApplication.java和RuoYiSystemApplication.java,对比它们的启动类代码,确认都是@SpringBootApplication注意网关启动类多了一个exclude = {DataSourceAutoConfiguration.class},思考为什么网关不需要数据源(答案:网关只做路由转发,不直接操作数据库)打开ruoyi-system/src/main/resources/application.yml,找到spring.application.name和server.port,记住这个服务名和端口打开script/config/nacos/dynamic_routes.json,找到ruoyi-system-api路由配置,确认/system/**路径会转发到lb://ruoyi-system第二课:服务注册与发现 Nacos对应代码:application.yml 中 nacos.discovery 配置 + ServerNameConstants2.1 问题:服务之间怎么找到对方?在单体应用里,Service A 调用 Service B 就是直接注入然后调方法。但在微服务里,认证服务需要调用系统服务查用户信息,它们是两个独立的进程,跑在不同的端口上。你可能会想:直接写死 IP 和端口不就行了?但问题是:服务有多个实例(负载均衡),写死只能调一个服务重启后端口可能变不同环境(开发/测试/生产)IP 不同2.2 解决方案:注册中心(电话簿模式)Nacos 就是一个"服务电话簿"。每个服务启动时做两件事:服务启动 │ ├── 1. 注册:告诉 Nacos "我叫 ruoyi-system,跑在 192.168.1.10:9201" │ └── 2. 心跳:每隔几秒告诉 Nacos "我还活着" 服务调用方 │ └── 问 Nacos "ruoyi-system 在哪?" → Nacos 返回:192.168.1.10:9201, 192.168.1.11:9201 → 调用方选一个发起请求2.3 看真实代码:服务怎么注册每个微服务的application.yml都有这段配置:spring:cloud:nacos:server-addr:127.0.0.1:8848# Nacos 地址username:nacospassword:nacosdiscovery:group:DEFAULT_GROUP# 注册到哪个组namespace:${spring.profiles.active}# 命名空间,用环境名隔离[!note] 关键概念namespace(命名空间):用环境名隔离,dev 环境的服务只跟 dev 环境的互通,不会误连到 prod。group(分组):同一环境下进一步分组,一般用 DEFAULT_GROUP 即可。spring.application.name:服务名,这是注册到 Nacos 的唯一标识。别的服务就是靠这个名字找到你的。2.4 服务名常量:统一管理项目把所有服务名定义在ServerNameConstants.java中:publicinterfaceServerNameConstants{// ruoyi-system 服务名StringSYSTEM_SERVER_NAME="ruoyi-system";// ruoyi-resource 服务名StringRESOURCE_SERVER_NAME="ruoyi-resource";// ruoyi-workflow 服务名StringWORKFLOW_SERVER_NAME="ruoyi-workflow";}这个常量在 Feign 调用时用到——告诉 Feign “我要调用哪个服务”。2.5 负载均衡:多个实例怎么选当一个服务部署了多个实例(比如 ruoyi-system 部署了 3 台),Nacos 返回一个实例列表,调用方需要选一个。这个工作由Spring Cloud LoadBalancer完成。在网关的路由配置中,lb://ruoyi-system的lb://前缀就是"负载均衡"的意思——不是直接连某个 IP,而是先问 Nacos 拿到实例列表,然后选一个。[!warning] 注意本项目源码内置了 Nacos(ruoyi-visual/ruoyi-nacos),不是从 Docker 拉取的官方镜像。好处是可以断点调试 Nacos 本身,坏处是启动时需要先编译这个模块。[!note] 本课小结Nacos = 注册中心 + 配置中心,类似电话簿服务启动时自动注册到 Nacos,靠spring.application.name作为唯一标识调用方通过服务名从 Nacos 获取实例地址,不写死 IPlb://前缀表示负载均衡,由 Spring Cloud LoadBalancer 选实例namespace 做环境隔离,group 做分组管理[!tip] 实操测试打开ruoyi-common/ruoyi-common-core/src/main/java/.../constant/ServerNameConstants.java,确认三个服务名常量打开ruoyi-auth/src/main/resources/application.yml,找到spring.application.name,确认值为ruoyi-auth对比 auth 和 system 的 application.yml,发现它们连的 Nacos 地址完全一样,只是服务名不同打开script/docker/docker-compose.yml,找到nacos服务定义,确认端口映射8848:8848如果本地已启动 Nacos,浏览器打开http://localhost:8848/nacos(用户名/密码 nacos/nacos),在"服务管理 → 服务列表"中能看到注册的服务第三课:API 网关 Gateway对应代码:ruoyi-gateway 模块全部 + dynamic_routes.json3.1 为什么需要网关如果没有网关,前端需要知道每个服务的地址:没有网关(混乱)前端 → http://localhost:9210/auth/login 前端 → http://localhost:9201/system/user 前端 → http://localhost:9204/resource/upload 前端 → http://localhost:9205/workflow/start 问题: - 端口暴露 - 每个服务都要处理跨域 - 每个服务都要做鉴权 - 前端配置复杂有网关(整洁)前端 → http://localhost:8080/auth/login 前端 → http://localhost:8080/system/user 前端 → http://localhost:8080/resource/upload 前端 → http://localhost:8080/workflow/start 好处: - 统一端口 8080 - 统一跨域处理 - 统一鉴权 - 前端只配一个地址3.2 网关的核心功能:路由路由规则存储在 Nacos 的dynamic_routes.json中,由NacosRouteDefinitionRepository加载:// dynamic_routes.json 中的路由示例{"id":"ruoyi-system-api","uri":"lb://ruoyi-system",// 转发到 ruoyi-system 服务"predicates":[{"name":"Path","args":{"pattern":"/system/**",// 匹配 /system/ 开头的请求"pattern1":"/monitor/**"// 也匹配 /monitor/}}],"filters":[{"name":"CustomStripPrefix","args":{"parts":"1"}// 去掉第一层路径前缀}]}[!note] 路由工作流程请求/system/user/list→ 匹配/system/**→ 去掉前缀变成/user/list→ 转发到ruoyi-system服务的/user/list3.3 动态路由:修改不重启看NacosRouteDefinitionRepository.java的核心逻辑:// 启动时从 Nacos 拉取路由配置@OverridepublicFluxRouteDefinitiongetRouteDefinitions(){Stringcontent=nacosConfigManager.getConfigService().getConfig(dataId,dataGroup,5000);ListRouteDefinitionlist=JSONUtil.toList(content,RouteDefinition.class);returnFlux.fromIterable(list);}// 监听 Nacos 配置变更,自动刷新路由privatevoidaddListener(){nacosConfigManager.getConfigService().addListener(dataId,dataGroup,newListener(){@OverridepublicvoidreceiveConfigInfo(StringconfigInfo){// 配置变更 → 发布事件 → 网关自动重新加载路由SpringUtils.context().publishEvent(newRefreshRoutesEvent(this));}});}这意味着你在 Nacos 控制台修改dynamic_routes.json,网关会立即生效,不需要重启。3.4 网关过滤器:鉴权看AuthFilter.java,这是网关最核心的安全防线:@ConfigurationpublicclassAuthFilter{@BeanpublicSaReactorFiltergetSaReactorFilter(IgnoreWhitePropertiesignoreWhite){returnnewSaReactorFilter().addInclude("/**")// 拦截所有请求.addExclude("/favicon.ico","/actuator/**").setAuth(obj-{SaRouter.

相关新闻

QKeyMapper:打破设备界限,让Windows输入控制随心所欲的终极解决方案

QKeyMapper:打破设备界限,让Windows输入控制随心所欲的终极解决方案

QKeyMapper:打破设备界限,让Windows输入控制随心所欲的终极解决方案 【免费下载链接】QKeyMapper [按键映射工具] QKeyMapper,Qt开发Win10&Win11可用,不修改注册表、不需重新启动系统,可立即生效和停止。支持游戏手…

2026/10/19 21:39:26 阅读更多 →
江苏成考本科可选专业汇总参考

江苏成考本科可选专业汇总参考

温馨提示:本文内容仅作参考,学费、录取分数线、当年招生专业等信息,最终以江苏省教育考试院通知、各院校继续教育学院公告以及报名系统公示内容为准。 不少打算在江苏报考成人高考本科的在职人员,想要了解现阶段可供选择的专业方向…

2026/10/17 15:05:04 阅读更多 →
教培SaaS线索分配系统的状态机设计从人工抢单到智能路由的演进

教培SaaS线索分配系统的状态机设计从人工抢单到智能路由的演进

背景教培机构的招生线索管理是一个典型的状态流转场景。一条线索从进入系统到最终成交或流失,会经历分配、跟进、试听、转化等多个状态。我们最初用status字段加if-else实现,随着业务复杂度增加,代码变成了面条式的条件判断,维护噩…

2026/10/15 12:13:01 阅读更多 →

最新新闻

2026年教育培训SaaS系统怎么选?从评价维度到避坑指南全解析

2026年教育培训SaaS系统怎么选?从评价维度到避坑指南全解析

第一次被培训机构老板问“哪家SaaS系统排名高”的时候,我记得很清楚,那是2018年,一个做少儿艺术培训的朋友拿着三份报价单来找我对比。那时候大家比的还是谁家的功能模块多、谁家的App长得好看。到了2026年,这个问题不但没变简单&…

2026/10/20 12:06:01 阅读更多 →
KECA核熵成分分析:训练测试集分离与数据泄漏避坑实践

KECA核熵成分分析:训练测试集分离与数据泄漏避坑实践

简介:这是一份面向非线性高维数据降维的KECA(核熵成分分析)MATLAB程序,适用于机器学习、模式识别及特征提取场景,尤其针对Q9A等需要核熵分析的实验问题。KECA结合核方法与熵理论,将数据映射到高维特征空间后…

2026/10/20 12:06:01 阅读更多 →
Kafka 2.8.0生产者消费者原生实现与高可用配置详解

Kafka 2.8.0生产者消费者原生实现与高可用配置详解

1. 项目概述:为什么一个“简单实现”值得花时间深挖?Kafka集群(2.8.0版本)之四:Java简单实现生产者和消费者——这个标题看起来平平无奇,甚至有点“教科书感”。但在我过去十年带团队落地消息中间件的实战中…

2026/10/20 12:06:01 阅读更多 →
MATLAB数据分析与挖掘实战:数据预处理、特征工程与建模避坑指南

MATLAB数据分析与挖掘实战:数据预处理、特征工程与建模避坑指南

简介:MATLAB数据分析与挖掘实战完整教程整合了配套源码、说明文档与真实数据集,面向工科生、数学专业及算法方向学习者,可系统演练数据导入、清洗、建模、评估与结果分析的完整链路,帮助理解数据挖掘中常用的预处理思路和建模方法…

2026/10/20 12:06:01 阅读更多 →
无GPU也能跑大模型:银河麒麟V10离线部署DeepSeek-R1全流程

无GPU也能跑大模型:银河麒麟V10离线部署DeepSeek-R1全流程

简介:面向银河麒麟V10操作系统技术人员的一份DeepSeek离线部署操作指南,重点解决在内网或无互联网环境下安装ollama大语言模型服务及chatbox客户端的问题。资源为单个docx文档,约2.69MB,内容涵盖系统环境与硬件检查、ollama解压安…

2026/10/20 12:06:01 阅读更多 →
KSyntaxHighlighting编译指南:解决KF6依赖与CMake构建链问题

KSyntaxHighlighting编译指南:解决KF6依赖与CMake构建链问题

1. 项目概述:为什么一个语法高亮库的编译会卡住你一整天?“编译 KSyntaxHighlighting 的过程中遇到的一些问题”——这个标题看起来平平无奇,甚至有点枯燥,但它背后藏着的是无数 C 跨平台开发者的共同记忆:一个看似轻量…

2026/10/20 12:05:01 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →