ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

若依Spring Cloud版本实操指南:从项目启动到微服务排错全记录

2026/9/8 0:06:53 拓冰建站 浏览量
若依Spring Cloud版本实操指南:从项目启动到微服务排错全记录 看到标题进来的多半是准备用若依Spring Cloud版本搭项目的朋友。我最近刚好把一个内部系统从若依单体版迁到了RuoYi-Cloud微服务版中间踩了不少坑也把官方文档里没写透的东西补了一遍。这篇就纯粹是我的实操记录从版本选型、项目结构、启动步骤到疑难杂症一次性写清楚。先说一个很多人容易搞混的点若依RuoYi官方其实有三条产品线最常用的是RuoYi单体版、RuoYi-Vue前后端分离版还有一条就是RuoYi-Cloud也就是标题里说的“Spring Cloud版本”。很多人把RuoYi-Vue当成了Spring Cloud版本实际上RuoYi-Vue还是单体架构只是前端分离了真正的微服务版是RuoYi-Cloud基于Spring Cloud Alibaba家族实现。本文聊的是后者。1. 为什么是若依Spring Cloud版本先想清楚再动手1.1 若依的三个主要版本应该怎么选我接触过不少朋友一上来就问“若依Spring Cloud版本怎么跑起来”其实他连RuoYi-Vue都没跑过。我的建议是如果你的目标是快速交付一个管理后台单机部署就够用那老老实实选RuoYi-Vue别碰微服务。微服务不是银弹它带来的注册中心、分布式事务、配置中心、日志链路每个都是需要运维成本的。RuoYi-Vue和RuoYi-Cloud在界面、业务代码上高度相似但底层架构差异很大。前者是单应用多模块打包成一个jar跑起来简单出了问题也好排查。后者拆分成网关、认证、系统、文件、定时任务多个服务虽然模块边界清晰了但启动和调试复杂度直线上升。如果你面对的是这样的情况才建议上RuoYi-Cloud系统里多个业务模块需要独立部署、独立扩缩容比如订单服务流量大要单独扩展用户服务不需要团队里已经有微服务的运维基础或者公司已经有Nacos、K8s这类基础设施明确未来会做服务拆分先把基座打好避免后面从单体一点一点拆出来的痛苦想在Spring Cloud Alibaba这套技术栈上做二次开发顺便沉淀团队技术能力。反过来如果是个人学习、毕设、小企业后台或者业务模块就三五个我劝你省点力气。我自己迁移之前也犹豫了很久最后是因为需要把报表、推送、权限三个模块独立部署才下定决心动的。1.2 迁移前需要接受的三件事第一学习成本比想象中高。RuoYi-Cloud虽然代码结构很清晰但你要先搞懂Nacos注册配置中心、Gateway网关、Feign远程调用、Sentinel限流这些概念对刚接触分布式的人来说是有门槛的。别指望一天跑通我前后花了将近一周才完全理顺。第二本地环境更吃内存。如果只启动核心链路网关、认证、系统大概需要3到4个Java进程每个默认堆内存512MB到1G加上Nacos、MySQL、Redis你的电脑如果低于16G内存会很难受。我一开始用8G内存的Air开发直接卡到怀疑人生。第三排查问题的范围变大了。单体应用报错就是那一个服务微服务报错可能是A服务调B服务的网络问题、B服务没注册上、配置没拉下来、鉴权没过任何一个环节断掉都会抛出类似“请求失败”的提示。你需要学会看Nacos服务列表、看网关日志、看Feign调用日志才能快速定位。但如果你已经决定要上那接下来的内容对你会有很大帮助。我记录的这套启动和排错流程是从一个完全没接触过RuoYi-Cloud的人的角度走的。2. 若依微服务版的项目结构与核心设计2.1 一眼看懂ruoyi-cloud的模块划分先把RuoYi-Cloud的模块结构说清楚。我用的版本是基于官方仓库的3.8.x分支下面这几个模块是最核心的ruoyi-gateway网关服务端口8080所有前端请求都走这里统一做路由转发、鉴权、限流ruoyi-auth认证服务端口9200负责登录、颁发token、刷新tokenruoyi-system系统服务端口9201用户、角色、菜单、部门这类核心业务逻辑都在这里ruoyi-file文件服务端口9300处理文件上传下载ruoyi-job定时任务服务端口9301基于Quartz的动态任务调度ruoyi-visual包含监控服务比如SkyWalking、Sentinel Dashboard这类可视化组件。除了业务服务还有一堆公共模块ruoyi-common-core、ruoyi-common-security、ruoyi-common-redis、ruoyi-common-log、ruoyi-common-datasource、ruoyi-common-job等。这些不是独立部署的进程而是被其他业务服务引用的jar包。我第一次看这个结构的时候最大的困惑是ruoyi-system明明包含了大部分业务表操作为什么还要单独拆一个ruoyi-auth出来后来看源码才明白网关只负责校验token是否存在、Redis中的用户信息是否有效真正的密码校验逻辑在认证服务里。权限验证也就是你能访问哪些接口则在网关做网关从Redis拿到用户权限列表比对当前请求的权限标识。这样设计的核心目的是让认证逻辑和业务逻辑完全隔离。哪怕你新增了订单服务、支付服务它们都只需要引入公共模块并注册到Nacos不需要再实现一遍登录和鉴权。这算是若依微服务版最值得学习的点。2.2 公共模块抽了什么为什么值得抽我单独说说ruoyi-common-core这个模块因为它的设计思路是面试中经常被问到的“抽取公共模块”这个话题的经典案例。它里面放的是Result返回体、分页对象、基础实体类、常量定义、工具类、异常处理等所有服务都依赖它避免了每个服务各写一套返回格式的问题。我实际迁移中最大的感受是微服务之间远程调用返回结果如果不统一联调起来非常痛苦。RuoYi-Cloud全链路都用R对象AjaxResult的分布式版本包了一层服务A调服务B拿到的永远是R对象先判断code是否为200再取data。这样在分布式环境下大家都约定好了一个“共同语言”。还有ruoyi-common-security模块它做的事情更多是在代码层面统一当前登录用户信息的获取方式。普通单体Web应用里直接用SecurityContextHolder.getContext()就能拿到用户微服务里Feign调用时目标服务也需要知道调用者是谁这就必须在请求头里透传用户信息并在目标服务里重新构建SecurityContext。RuoYi-Cloud把这个逻辑封装在了一个叫HeaderInterceptor的拦截器里这个细节后面我会细说。现在市面上的很多脚手架比如芋道框架这类当初也是从若依改造过来的虽然它们后续加了很多自己的东西但如果你能把RuoYi-Cloud这套公共抽取思路吃透再去看那些更复杂的框架会轻松很多。2.3 一次登录背后的鉴权链路token怎么构造和传递面试的时候经常有人问“Spring Cloud微服务之间怎么保持登录状态”RuoYi-Cloud的实现就是一个标准答案。我画不了图用文字把这个链路完整描述一遍。用户在前端输入用户名密码请求发送到网关网关路由到认证服务。认证服务拿到用户名密码后调用system服务里的用户信息表校验账号状态和密码校验通过后生成一个UUID作为token同时把用户ID、用户名、权限标识列表等信息组装成LoginUser对象以token为key存储到Redis。这个token返回给前端后前端每次请求都会在Header里带上“Authorization: Bearer token”。网关收到请求后会先走AuthFilter过滤器这个过滤器做两件事第一从Redis查询token是否存在不存在直接返回401第二查询出来的LoginUser信息会被放回请求Header中继续向下游服务转发。那下游服务怎么拿到用户信息呢我前面提到的HeaderInterceptor在起作用。网关转发的请求到达system服务或者其他业务服务时会被这个拦截器拦截它从请求头里取出用户ID、用户名、用户Key等信息重新构建Authentication对象塞入SecurityContextHolder。这样在业务代码里你依然可以用SecurityUtils.getUserId()这种写法拿到当前操作人和单体应用几乎没有区别。我认为这个设计最值得学习的地方在于它把“登录状态校验”和“业务服务内部用户信息获取”两个问题完全解耦了。业务服务不需要关心token怎么生成、怎么存储只需要信任网关透传过来的Header即可。这也是微服务架构里一种比较经典的透传方案很多企业项目都是这么做的。3. 从零启动若依Spring Cloud版本的完整记录3.1 环境准备JDK、Maven、MySQL、Redis、Nacos先把基础环境准备好。我用的组合是JDK 1.8、Maven 3.6.3、MySQL 5.7、Redis 6.x、Nacos 2.2.3。新版本若依支持JDK 17但我建议首次跑通别追新JDK 8 Spring Boot 2.x的组合经过了最多人验证遇到问题随便搜都有答案。Maven建议用阿里云私服镜像不然下载Spring Cloud Alibaba全家桶会慢到怀疑人生。在settings.xml里配置mirror把central镜像换成阿里的地址这个操作我现在每次搭环境都做。MySQL需要准备两个库一个是若依业务库一个是Nacos的配置库。若依官方仓库的sql文件夹下会有对应的脚本文件把业务库脚本导入后你就能看到sys_user、sys_role、sys_menu这些非常熟悉的管理后台表。Nacos的配置库则是nacos_config相关脚本Nacos开启持久化后会用到。Redis一般默认配置即可但有一点要注意检查Redis密码配置文件和若依里的默认配置是否对得上。若依默认配置YAML里Redis密码为空如果你本机Redis设置了密码记得改配置否则认证服务启动后读写Redis直接报错。Nacos我用的是Docker方式一条命令就能跑起来docker run -d --name nacos -p 8848:8848 -p 9848:9848 \ -e MODEstandalone \ -e SPRING_DATASOURCE_PLATFORMmysql \ -e MYSQL_SERVICE_HOST127.0.0.1 \ -e MYSQL_SERVICE_DB_NAMEnacos_config \ -e MYSQL_SERVICE_PORT3306 \ -e MYSQL_SERVICE_USERroot \ -e MYSQL_SERVICE_PASSWORDyourpassword \ nacos/nacos-server:v2.2.3注意如果是本地Docker访问宿主机的MySQLhost要写成host.docker.internal而不是127.0.0.1这个问题当年困扰了我一个晚上。Nacos启动后访问8848端口默认账号密码都是nacos。3.2 初始化数据库与Nacos配置数据库脚本执行完下一步是导入Nacos配置。这一步很多新手会漏掉导致后面每个服务启动时都在疯狂报“找不到配置”。RuoYi-Cloud的Nacos配置是放在项目sql文件夹里的一个独立脚本类似ry_config.sql执行之后你会看到Nacos控制台里出现几十个配置文件和几个配置分组。这些配置就是各个服务的application.yml包括数据库连接、Redis地址、MQ、文件上传路径等。这里有个关键点若依把服务配置拆成了几个共享配置文件例如数据源配置、Redis配置、通用配置各服务再通过Nacos的shared-configs机制引用。所以在改数据库密码时你只需要改公共配置里的那一份所有服务都会生效。这个设计很巧妙也提醒我们改配置不能在服务自己的yml里乱改否则会被Nacos里的配置覆盖掉。配置导完之后建议在Nacos控制台的“配置列表”里随便点开一个文件核对数据库密码、Redis地址是否正确。尤其是换机器部署的人最容易忘记改这里服务启动的时候报数据库连接失败第一反应是改代码里的yml结果改了半天还是不行最后发现Nacos配置中心里的密码还是旧的。3.3 按顺序启动服务并验证登录启动顺序我按下面这个顺序来基本没出过问题第一步启动Nacos确认控制台可以访问。 第二步启动网关服务ruoyi-gateway。网关启动后在Nacos服务列表里应该能看到它注册成功。 第三步启动认证服务ruoyi-auth。 第四步启动系统服务ruoyi-system。 第五步启动前端。若依的微服务版对应的是RuoYi-Vue的前端项目启动后默认端口是80或8080需要在vue.config.js里把代理指向网关的8080端口。如果以前跑过单体版RuoYi-Vue你会发现一件事单体版前端代理指向的是后端服务的端口比如8080就是后端应用自己微服务版前端代理指向的还是8080但那是网关的端口。这个区分很重要我之前就犯过把前端代理指到9201system服务端口的错结果登录接口能通但其他接口全部404。全部启动完成后打开前端页面用默认账号admin/admin123登录。登录成功后打开浏览器开发者工具看Network面板登录请求POST /login返回了token之后的所有请求Header里都带着Authorization如果某个请求返回401去查网关日志里AuthFilter的校验信息。我第一次跑通登录流程时看到系统管理菜单里能正常加载用户列表那种感觉还是很踏实的。到这一步核心链路基本正常接下来就是按自己的业务做二次开发。4. 玩转Nacos配置与网关限流4.1 Nacos配置中心的目录结构和共享配置既然用了Nacos就别把配置继续写在项目里的application.yml中。RuoYi-Cloud的做法是把每个服务自己的配置放到Nacos本地yml只保留应用名、端口、环境标识这些启动必需的信息剩下的全部外置。你在Nacos里会看到类似这样的配置条目ruoyi-gateway-dev.yml网关路由规则、限流规则、放行白名单ruoyi-auth-dev.yml认证服务的token有效期、密钥配置ruoyi-system-dev.yml业务数据库连接、MyBatis配置、文件上传路径ruoyi-redis-dev.ymlRedis公共配置ruoyi-datasource-dev.yml多数据源公共配置。其中ruoyi-redis-dev.yml和ruoyi-datasource-dev.yml这种共享配置是通过各服务Nacos配置里配置的shared-configs引入的。这个机制的好处是如果你新增了一个订单服务只需要在它的Nacos配置里同样引入这两份共享配置然后写自己的业务配置即可不需要把数据源和Redis再抄一遍。我后来把自己开发的模块也按这个模式接入非常顺手。你只需要注意一点共享配置ips里的键值不要随意改成不同服务的个性配置比如某个服务用的Redis库号不同就应该在自己服务的配置里覆盖redis.database这个键而不是去改共享配置。配置修改后Nacos会自动推送给已订阅的服务不需要重启。但是如果修改了端口、服务名这类关键配置最好还是重启服务因为像注册到Nacos的服务实例元数据不会自动更新。4.2 网关路由与Spring Cloud Gateway限流配置RuoYi-Cloud的网关路由规则在ruoyi-gateway-dev.yml里可以直观看到它是基于路径前缀做转发的以/auth开头的请求转发到ruoyi-auth服务以/system开头的请求转发到ruoyi-system服务以/file开头的请求转发到ruoyi-file服务。路由配置本身不难面试中被问到的“Spring Cloud Gateway如何限流”其实在RuoYi-Cloud里就有现成答案。网关模块里默认集成了RequestRateLimiter过滤器这是Spring Cloud Gateway官方提供的限流能力基于Redis Token Bucket算法实现。配置大致长这样spring: cloud: gateway: routes: - id: ruoyi-system uri: lb://ruoyi-system predicates: - Path/system/** filters: - name: RequestRateLimiter args: redis-rate-limiter.replenishRate: 10 redis-rate-limiter.burstCapacity: 20 key-resolver: #{remoteAddrKeyResolver}这里的replenishRate是每秒向桶里放入的令牌数burstCapacity是桶的容量。通俗理解就是每秒最多放行10个请求允许瞬时突增到20个超过的直接返回429状态码。key-resolver指定的remoteAddrKeyResolver则是根据客户端IP来区分不同的限流维度这个类在网关模块的config包下可以找到源码。我自己做压测的时候调过这个参数当并发请求超过burstCapacity时接口响应状态码变成HTTP 429页面表现为部分请求加载失败但HTTP服务不会宕机说明限流确实生效。如果业务场景需要按用户维度限流可以把key-resolver改成从Header里取用户ID这在若依里是很容易改的因为网关已经解析过token并放入了用户信息。如果你在复习Spring Cloud面试题记住这套实现逻辑基本足够应付“网关限流怎么实现”这类问题比单纯背概念强得多。5. 若依微服务版常见问题与排查实操清单5.1 启动阶段的典型问题先列一个我实际遇到的启动问题速查表这些都是新手高频踩坑点问题现象可能原因排查方法服务启动后一直打印“nacos registry register failed”Nacos未启动或者服务里Nacos地址配置错误打开Nacos控制台确认可访问检查配置中心里的地址和端口启动报“Data source ... not configured”Nacos中共享数据源配置里的数据库密码或地址不对把Nacos中的ruoyi-datasource-dev.yml和DB实际参数对照认证服务启动报Redis连接失败Redis密码或端口配置问题看配置中心里的Redis配置检查本机Redis是否启动网关能启动但浏览器访问前端页面接口全部404前端代理指向了业务服务端口而不是网关修改vue.config.js代理目标为网关8080端口Nacos服务列表能看到服务但服务间Feign调用报Load balancer错误服务没有正确注册或版本不匹配确认调用方和被调用方都注册在同一个namespace检查依赖版本一致性这里我特别提一下Nacos的namespace命名空间问题。如果你在Nacos控制台手动创建了命名空间而服务的namespace配置还是public默认就会导致服务找不到配置文件或者互相找不到服务。RuoYi-Cloud默认都走public命名空间你在初始化时最好不要为了“整洁”去建新命名空间除非你确定知道自己在做什么。另外还有一个我印象很深的坑Nacos从1.x升级到2.x之后多了9848这个gRPC端口。本地开发如果只开放了8848服务虽然能注册但偶尔出现服务下线不及时、调用超时的情况。这时记得把9848端口也放通防火墙、云安全组里一起配置好。5.2 登录鉴权与跨服务调用问题登录这块出现频率最高的问题是“登录成功后过一会儿请求又401”。这个多半和token有效期、Redis里的过期时间有关。RuoYi-Cloud默认token有效期存在Nacos配置里字段叫token.expireTime单位是分钟。如果完全默认一般不会很快过期。但如果你的服务器时区或系统时间不对可能导致Redis的过期时间计算异常。如果遇到所有请求都401先检查Redis里是否真的存在token对应的key。可以在Redis里执行keys *login_tokens:*如果有key再执行ttl login_tokens:xxxxxxxxxxx查看剩余过期时间。如果key不存在说明认证服务写Redis失败多半是前面说的Redis配置问题。这个排查路径能帮你把问题从“代码bug”快速缩小到“配置问题”。还有一类问题是下游服务A调用服务B时B返回401。这通常是Header透传没生效。RuoYi-Cloud在公共模块里已经实现了Feign的RequestInterceptor会自动把当前请求里的Header往下游传递。如果你在自己新写的模块里自定义了Feign配置可能会覆盖掉这个拦截器导致透传失效。我的建议是要么不要自定义全局Feign配置要么一定要在自定义配置里加载若依的AuthRequestInterceptor。5.3 新模块接入时最容易被忽略的配置很多人会按RuoYi-Cloud的教程新增一个自己的业务服务比如ruoyi-orders。按照官方步骤走大部分人都能启动成功但有几个细节很容易被忽略。第一新服务的bootstrap.yml里一定要配置Nacos的服务发现和配置中心地址否则服务根本不会注册到Nacos。第二新服务的Maven依赖里如果涉及数据库操作要引入ruoyi-common-datasource如果涉及权限校验要引入ruoyi-common-security。漏一个启动时就会报缺少类或者数据库Session工厂找不到。第三新服务需要在前端网关路由配置里加一条路由规则否则前端请求打过来网关直接404。这个路由规则的配置路径就是前面说的ruoyi-gateway-dev.yml。很多人在本地测试时绕过了网关直接访问新服务的端口导致前端上线后接口全挂这个问题我在项目里帮别人排查过好几次。如果只是想快速验证新服务能不能被其他服务调用最直接的方法是在Nacos服务列表里看到自己的服务名然后在任意一个已有服务里写一个Feign接口调用它。这个方法比从前端一步步走快很多适合开发期自测。最后再分享一个小技巧我个人实际开发中的体会是RuoYi-Cloud这套东西表面上是个权限管理后台实际上是一个非常好的Spring Cloud Alibaba学习教材。它的代码量不大但把网关、注册配置中心、远程调用、权限透传、定时任务、文件服务都串起来了。后来我面试实习生的时候也经常拿RuoYi-Cloud当切入点让对方讲讲token怎么在多个微服务之间传递、网关限流怎么配置。能把这套讲明白的人至少说明他不是只会写CRUD。所以如果你正在学Spring Cloud与其漫无目的地看教学视频不如直接把若依微服务版跑起来跟着源码去断点调试一遍登录流程收获会大得多。还有个小建议第一次跑通之后别再继续用官方默认的前端页面试着在上面加一个业务模块从建表到写接口再到前端页面完整走一遍这样才算真正掌握。