
简介一套基于若依框架的Spring Cloud与Spring Cloud Alibaba微服务前后端分离项目面向Java后端、架构设计及微服务转型开发者适用于企业级中后台系统搭建与二次开发。项目核心围绕微服务落地常见痛点展开Nacos承担注册与配置中心Sentinel实现限流与熔断Seata处理分布式事务Redis支撑权限认证前端采用Vue3、Element Plus与Vite构建整体按网关、认证、系统、文件、监控、代码生成、定时任务等模块拆分结构清晰。压缩包共677个文件约132.24MB主要包括261个Java后端源码、89个Vue前端组件、75个JS脚本、46个XML与10个YML配置文件另有Dockerfile便于容器化部署SQL脚本可快速初始化数据库并附带启动、打包批处理及部署脚本降低环境搭建门槛。目前已有3578人学习下载适合需要快速搭建可运行微服务工程、深入理解Spring Cloud Alibaba组件整合方式或基于RuoYi-Cloud扩展业务的读者借鉴。1. Spring Cloud 全家桶装不好后面全是补窟窿把 SpringCloud、Nacos、Sentinel、Seata 和 Vue3 揉在同一个脚手架里跑起来是很多团队做微服务改造的第一步也是最近后台开发群里被问得最多的一件事。这套环境太常见了网上代码仓库一搜一大把但真正卡人的从来不是写业务而是版本配对和中间件启动。Nacos 注册中心起不来、服务注册不上、Sentinel 限流规则不生效、Seata 分布式事务回滚没反应、Vue3 前端联调跨域任何一个环节翻车排查时间都是以小时计的。这篇文章就是我从零搭这套全家桶的记录适合刚拿到脚手架准备在自己服务器或本机部署的开发者照着走也适合已经装过但被各种玄学报错折磨的人回来对参数。2. 装底座JDK、Maven、Node、MySQL 的版本选择和一次到位2.1 先定版本再谈安装很多新手一上来就下载最新版结果一下午全在跟编译错误搏斗。这套脚手架最坑的地方就是版本配对Spring Boot、Spring Cloud、Spring Cloud Alibaba 三者必须按兼容矩阵来选错一位整个项目连编译都过不去更别谈启动。我这边用的组合是 Spring Boot 2.6/2.7 这个区间配合 Spring Cloud 2021.x、Spring Cloud Alibaba 2021.xJDK 用 8 或 11 都能跑。为什么不推荐一步到位上 Spring Boot 3因为 Nacos、Sentinel、Seata 的客户端依赖在 Spring Boot 3 下的适配还不算稳很多脚手架分支根本没有维护你装上以后出问题查遍全网都找不到对应答案。数据库方面MySQL 用 5.7 或 8.0 都行但 8.0 必须注意时区参数否则连不上或者报时区错误。前端这边 Node 必须是 16 以上Vue3 Vite 这种组合在低版本 Node 上会直接报错连依赖都装不完。Maven 用 3.6 以上版本。先把这个版本表定死后面每一步都按这个来能少踩一半坑。2.2 JDK 安装手动解压代替包管理器我习惯手动解压 JDK不用系统自带的 openjdk因为版本不好控制和切换。先把 jdk 的 tar.gz 包上传到服务器比如放在 /opt/src 下然后按下面的流程来。mkdir -p /opt/java tar -zxvf jdk-8uXXX-linux-x64.tar.gz -C /opt/java/ ln -sfn /opt/java/jdk1.8.0_XXX /opt/java/current cat /etc/profile EOF export JAVA_HOME/opt/java/current export PATH$JAVA_HOME/bin:$PATH EOF source /etc/profile java -version这里的软链接是为了以后升级 JDK 方便只需要重新解压再改一下软链不用动环境变量。很多运维不喜欢做软链但在这套微服务环境里后面可能要同时跑 JDK 8 和 JDK 11 的服务软链切换是最省事的方案。source /etc/profile只对当前会话生效如果你用的终端连的是远程 SSH重开一个窗口会话即可。2.3 Maven配好国内镜像和本地仓库Maven 解压到 /opt/maven然后必须改 conf/settings.xml。我一般会同时配置本地仓库路径和镜像地址不然下载 Spring Cloud Alibaba 那一堆依赖能把人等崩溃。localRepository/opt/maven/repo/localRepository mirrors mirror idnexus/id mirrorOf*/mirrorOf nameNexus Mirror/name urlhttps://maven.aliyun.com/repository/public/url /mirror /mirrors镜像用国内仓库就行具体地址以你自己环境能访问的为准。注意mirrorOf*/mirrorOf意思是所有依赖都走这个镜像包括插件如果某些私服依赖也在里面就改成central只代理中央仓库。本地仓库路径建议固定不要用默认的~/.m2因为后面用 Jenkins 或脚本构建时不同用户下~/.m2路径不一致会导致重复下载。2.4 Node 环境用 nvm 锁版本装完系统自带的 node 之后直接跑npm install报错是常有的事因为版本太新或太老。我推荐用 nvm 来装好处是可以在 16 和 18 之间随时切换。curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash source ~/.bashrc nvm install 16.20.2 nvm alias default 16.20.2 node -v npm config set registry https://registry.npmmirror.comnvm 装上以后nvm alias default一定要设否则每次新开终端又回到系统自带 node前端项目直接起不来。npm 配国内镜像属于常规操作不配的话 vite 装依赖要等很久而且经常抽风失败。装完之后顺手执行npm config list看一眼 registry 是不是已经生效。2.5 MySQL 初始化建库导入脚本脚手架一般自带 SQL 脚本目录里面是一堆建库建表语句。这一步容易忽略的是字符集和排序规则我习惯统一用 utf8mb4避免后面用户在页面上输入表情符号直接报错。CREATE DATABASE IF NOT EXISTS ry-cloud DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; CREATE DATABASE IF NOT EXISTS nacos_config DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; CREATE DATABASE IF NOT EXISTS seata_server DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; SOURCE /opt/src/sql/ry_2024xxxx.sql;先建三个库业务库、Nacos 配置库、Seata 事务库。然后按顺序执行脚手架自带的 SQL 脚本先执行系统库脚本再执行业务模块脚本。如果脚本里存在外键依赖必须按脚本注释里的顺序导入直接一股脑全执行会报错说表不存在。导入完成后用show tables;抽查几张表确认数据真的进去了别急着往下走。3. 部署 Nacos注册中心与配置中心一台就位3.1 单机启动前必须改的四个参数Nacos 用 2.x 系列目前主流脚手架适配的也是这个系列。拿到 nacos-server 包后解压到 /opt/nacos先不要急着启动打开 conf/application.properties 改四类东西端口、数据库连接、鉴权开关、token 密钥。如果你不连 MySQLNacos 也可以用内嵌 Derby 数据库跑单机但集群和正式环境我从不这么干因为数据很容易丢而且没法跟其他服务共享配置数据。server.port8848 spring.datasource.platformmysql db.num1 db.url.0jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncodingutf8connectTimeout1000socketTimeout3000autoReconnecttrueuseUnicodetrueuseSSLfalseserverTimezoneAsia/Shanghai db.user.0root db.password.0你的数据库密码 nacos.core.auth.enabledfalse nacos.core.auth.plugin.nacos.token.secret.keyVGhpc0lzTXlDdXN0b21TZWNyZXRLZXkwMDE数据库连接串里的serverTimezoneAsia/Shanghai不能省MySQL 8.0 的驱动对时区要求很严格不加这个连启动都会失败。鉴权开关这里先设置为关闭因为内网部署调试阶段开鉴权会让服务注册和配置拉取的排查多一层变量。但是注意token.secret.key这个参数即使不开鉴权也要留一个足够长的值Nacos 2.x 对密钥长度有校验短了会直接启动失败这个坑我踩过一次关键词是“启动日志里报 malformed”。数据库初始化时需要先把 Nacos 自带的 conf/mysql-schema.sql 导入到 nacos_config 库里注意这个脚本 Nacos 包里有不要自己建表直接执行即可。确认无误后再回 bin 目录启动单机实例。3.2 启动与验证看日志而不是看端口启动命令很简单真正麻烦的是怎么判断启动成功。很多同学netstat -tlnp | grep 8848看到端口在监听就说启动成功了结果服务注册进来全报错。我一般用下面的方式启动然后直接看启动日志。cd /opt/nacos/bin sh startup.sh -m standalone tail -f /opt/nacos/logs/start.out看到日志里出现Nacos started successfully才算真正的启动成功。如果是Nacos did not start说明配置有问题常见的就是数据库连不上、密钥太短、端口被占用。另外 Nacos 2.x 启动后还会额外监听 9848 和 9849 两个 gRPC 端口这是给客户端长连接用的很多环境只放行了 8848导致服务注册心跳全失败界面看到服务时有时无根因是防火墙没放行 9848。这一条记下来后面排查会用到。3.3 微服务接入注册中心namespace 和 group 必须统一后端的每个微服务都需要在配置文件里接上 Nacos现在主流做法是拆成两个文件bootstrap.yml 负责拉取配置中心的数据application.yml 只保留本地的非配置中心参数。bootstrap.yml 里这样配spring: application: name: demo-system cloud: nacos: discovery: server-addr: 127.0.0.1:8848 namespace: dev group: DEFAULT_GROUP config: server-addr: 127.0.0.1:8848 namespace: dev file-extension: yaml group: DEFAULT_GROUPnamespace 用 devgroup 用 DEFAULT_GROUP这样一套环境里所有服务都在同一个命名空间下互相可见。如果 namespace 写错或者不写会出现服务能注册到 Nacos 但网关路由找不到目标服务的情况界面上的服务列表和你实际加载的配置完全对不上排查起来非常浪费时间。配置中心的 dataId 规则是${spring.application.name}.${file-extension}比如 demo-system.yaml。也就是说你要在 Nacos 配置中心新建一个 dataId 叫 demo-system.yaml 的配置服务启动时才会拉取到。如果脚手架在配置文件里还指定了shared-configs或extension-configs也要在 Nacos 里完整建好缺任何一个服务起来就报找不到配置。3.4 把公共配置抽到 Nacos配置中心的正确用法本地 application.yml 里只留应用名、端口、profiles 这些启动前置信息数据源、Redis、日志级别、自定义业务开关这些配置全部抽到 Nacos 的配置中心里存起来。这样做的好处是改配置不用重新发包在 Nacos 控制台上改完点发布服务端会自动刷新。对于多环境也可以通过 namespace 隔离 dev、test、prod共用一套配置模板。我见过很多人把数据库密码直接写在本地配置文件里然后 Nacos 那边只放一个空的配置这样配置中心完全没有用起来后面改一次数据库密码要改十几台服务纯属自找麻烦。正确姿势是本地文件只写 spring.cloud.nacos 相关的连接信息和应用名其他全放云端。另外配置中心的配置文件内容要和本地原来的配置结构保持一致后缀按 bootstrap.yml 里 file-extension 配的来yaml 就用 yamlproperties 就用 properties混用会解析失败。4. Sentinel 与 Seata限流熔断和分布式事务落地4.1 Sentinel 控制台部署改端口再启动Sentinel 分两块控制台是单独的 Java 应用负责配置规则和看监控客户端是嵌入微服务里的依赖包。控制台官方默认端口是 8080但这跟微服务网关端口常常撞车我一般直接指定成 8858。java -Dserver.port8858 -Dcsp.sentinel.dashboard.serverlocalhost:8858 -Dproject.namesentinel-dashboard -jar sentinel-dashboard-1.8.6.jar启动后浏览器访问http://服务器IP:8858默认账号密码都是 sentinel登录后界面是空白的这不代表没启动成功而是还没有任何客户端接入进来。控制台不要用太新的版本要和脚手架里 Spring Cloud Alibaba 的版本匹配版本差太远会出现客户端上报数据但控制台不显示或者规则同步不过去的情况。我用的组合里 Sentinel 客户端和服务端都是 1.8.x 这一代稳定。4.2 微服务接入 Sentinel依赖和规则推送在需要做限流熔断的服务里引入 Sentinel 的 Spring Cloud 适配依赖然后在 yml 里指定控制台地址spring: cloud: sentinel: transport: dashboard: 127.0.0.1:8858 port: 8719 eager: true这里的port: 8719是客户端和控制台通信的本地端口默认是 8719如果被占用会自动向后找端口但会有一个启动警告。eager: true的意思是服务启动时就主动连上控制台而不是第一次被访问时才建立连接。如果不加这个参数你启动服务后等半天控制台里都没出现服务就会误以为接入失败。规则配置方面Sentinel 支持在控制台上手动新增流控规则、熔断规则但要注意默认模式是内存态控制台重启规则就没了。如果你希望规则持久化需要在项目里引入 datasource 扩展把规则存到 Nacos 配置中心这个比较进阶新手阶段先手动在控制台配几组规则验证通了再考虑持久化。4.3 Seata Server 部署注册到 Nacos 上Seata 这套东西说复杂也复杂说简单也简单核心是把分布式事务的协调器TC单独部署让所有微服务通过它来做全局事务协调。我部署的 Seata 是 1.5/1.6 这个系列服务端拿到包以后解压到 /opt/seata重点是改两个文件conf/registry.conf 和 conf/file.conf。registry.conf 里把注册中心指到 Nacosregistry { type nacos nacos { application seata-server serverAddr 127.0.0.1:8848 group DEFAULT_GROUP namespace username password } }file.conf 里重点改事务组映射和存储方式。现在新版的 Seata 把配置拆到 config.conf 或者 application.yml 里了但事务组这个概念还在。关键是service.vgroupMapping里的 key比如my_test_tx_group这个名称要和客户端里配置的事务组名完全一致多一个字符少一个字符都不行。存储我建议直接改成数据库模式这样事务日志重启不丢方便定位问题。然后去 Nacos 配置中心里把 Seata 客户端要用的配置项整理好同时执行 Seata 官方提供的 undo_log 建表脚本这个脚本要分别到每个涉及分布式事务的业务库里执行CREATE TABLE IF NOT EXISTS undo_log ( id BIGINT NOT NULL AUTO_INCREMENT, branch_id BIGINT NOT NULL, xid VARCHAR(100) NOT NULL, context VARCHAR(128) NOT NULL, rollback_info LONGBLOB NOT NULL, log_status INT NOT NULL, log_created DATETIME NOT NULL, log_modified DATETIME NOT NULL, ext VARCHAR(100) DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY ux_undo_log (xid, branch_id) ) ENGINE InnoDB AUTO_INCREMENT 1 DEFAULT CHARSET utf8mb4;这张 undo_log 表是 Seata 做回滚的核心里面存的是一阶段业务数据的前后镜像。很多同学说 Seata 不回滚第一反应是代码问题我第一个查的就是这张表存不存在十有六七是表没建。4.4 微服务接入 Seata 客户端事务组名要对齐客户端接入比服务端简单只要引入 seata-spring-boot-starter 依赖然后在配置文件里配上服务端地址和事务组名seata: enabled: true application-id: demo-system tx-service-group: my_test_tx_group registry: type: nacos nacos: server-addr: 127.0.0.1:8848 group: DEFAULT_GROUP这里最坑的就是tx-service-group必须和 seata server 端 file.conf 里vgroupMapping的 key 一致。比如服务端配置的是my_test_tx_group default客户端这里就必须写my_test_tx_group。写错的话服务启动时不报错但你调用跨服务接口时事务分支根本不会注册到 TC 上界面上看不到任何异常只有当你故意制造一个异常测试回滚时才发现完全没反应。事务的开启是在事务发起方的方法上加上GlobalTransactional注解注意是 Global 开头的这个不是本地事务的Transactional。很多同学只加了本地事务注解然后跨服务调用数据写了一半另外一个服务抛异常第一个服务根本不会回滚这是分布式事务的经典误用。5. 前后端联调常见问题排查与避坑记录5.1 后端微服务启动顺序和端口规划整套环境最忌一股脑把所有 jar 包同时启动服务有依赖关系顺序不对会出现各种间歇性报错。我的启动顺序是先确保 Nacos 和 Seata Server 完全就绪再启动网关再启动认证服务和系统服务最后启动业务模块。当然如果都注册到 Nacos 了理论上不管先启动谁最终都能互相发现但网关这种东西是流量入口它晚于服务启动会导致用户请求打过来时路由还没建立。我一般写一个简单的启动脚本# 先启动网关 nohup java -jar demo-gateway.jar --server.port8080 /var/log/gateway.log 21 # 再启动系统服务 nohup java -jar demo-system.jar --server.port9200 /var/log/system.log 21 # 启动业务服务 nohup java -jar demo-job.jar --server.port9300 /var/log/job.log 21 启动后立刻用tail -f盯日志看到Started DemoSystemApplication再启动下一个。这里要注意不同模块的端口是在 Nacos 配置中心上统一管理的jar 包启动时通过--server.port指定的优先级高于配置文件但如果你把端口写在 Nacos 配置里了命令行这个参数会被覆盖实际生效的以 Nacos 上的配置为准。5.2 Vue3 前端启动代理配好就成功了一半前端项目用 Vue3 Vitenpm install 完之后直接 npm run dev浏览器访问模板里写的地址。如果页面能打开但接口全部请求失败十有八九是 vite 代理没配对。// vite.config.js server: { host: 0.0.0.0, port: 80, proxy: { /api: { target: http://127.0.0.1:8080, changeOrigin: true, rewrite: (path) path.replace(/^\/api/, ) } } }/api前缀的请求全部转发到网关的 8080 端口changeOrigin必须开否则后端拿到的 Host 头是前端地址某些鉴权过滤器会直接拦掉。rewrite这一段要看脚手架的网关路由规则有些项目后端接口本来就不带 /api 前缀那就需要把前缀剥掉再转发。前端登录之前先在浏览器 F12 里确认/login请求是否真的打到了后端状态码是不是 200这一步能定位掉一大半问题。5.3 高频踩坑现象、原因、解决办法这套环境我前前后后搭了不下五遍把最容易让人浪费时间的坑集中列出来每一条都是真实经历过的。报错一服务启动时报连不上 Nacos现象是启动日志里抛Client not connected, current status:STARTING然后服务反复重试。先排查网络能不能通在微服务机器上执行telnet 127.0.0.1 8848能通的话再检查 9848 端口通不通因为 Nacos 2.x 客户端实际用 gRPC 长连接只通 8848 不够。然后确认 server-addr 写的是不是 IP:端口我见过有人在 yml 里写了域名但机器没配 hosts导致一直解析失败。报错二Nacos 控制台服务列表为空服务明明起来了控制台却不显示任何实例。原因基本都是 namespace 不一致。服务注册时你在 yml 里配了 namespace: dev那么控制台左上角必须切换到 dev 这个命名空间再看。此外 group 不一致也会导致列表为空服务端默认注册到 DEFAULT_GROUP如果控制台查询条件选了其他 group自然看不到。检查方式很简单把 yml 里的 namespace 和 group 与控制台的筛选条件逐项对齐。报错三配置中心拉不到配置服务起不来服务启动时如果 Nacos 配置中心里找不到对应的 dataId启动会直接失败。此时进入 Nacos 控制台的配置管理看是否存在${spring.application.name}.yaml这个 dataId注意分隔符是点不是横线。如果项目里配置了shared-configs也要确保这些扩展配置都在 Nacos 里存在文件扩展名与 yml 中file-extension设置一致。报错四Seata 全局事务不回滚现象是发起方方法抛了异常但前一个服务的数据库数据没有被回滚。先查事务发起方的方法上是不是加的GlobalTransactional再查各个业务库里有没有undo_log表然后核对客户端tx-service-group和服务端事务组名是否完全一致。这三步检查完基本能覆盖 90% 的场景。最后一步是看 Seata Server 日志如果客户端从来没注册过分支事务日志里会一片安静。报错五Sentinel 限流规则不生效控制台登录后配置了一条限流规则结果压测的时候没有任何拦截。先确认服务真的接入到了控制台也就是服务列表里能看到这个应用。然后确认你配置规则的资源名和代码里SentinelResource注解的 value 是完全一致的资源名是精确匹配多个空格或大小写差异都匹配不上。Sentinel 默认的限流效果是 fastfail如果直接返回错误码而不是抛异常很多同学以为是规则没生效其实是生效了但表现方式不同。报错六前端一直转圈接口 404 或跨域接口能通到后端但返回 404一般是网关路由规则里没有配置该服务对应的路由如果返回跨域报错则是 vite 代理的changeOrigin没开或者根本没走代理。我在排查时习惯先看前端 Network 面板里请求的完整 URL如果 URL 里还是 80 端口且不是 /api 开头说明代理没匹配上去翻 vite.config.js 的 proxy 配置把前缀核实清楚。6. 装完怎么验证一条链路确认微服务真的跑通6.1 四步验证链路环境全部搭完以后不要直接开始写业务先花十分钟做一轮链路验证确认每个环节都真的通了再去碰代码。我习惯按下面的顺序走一遍。第一步打开 Nacos 控制台切到 dev 命名空间确认服务列表里网关、认证、系统服务等所有服务都显示在线实例数不为 0健康状况是绿色。如果某个服务不在列表里直接把这个服务的日志翻出来看注册相关的报错。第二步随便选一个已经在 Nacos 配置中心管理的配置项比如日志级别改一下再点发布回到服务日志里看有没有出现Refresh completed之类的刷新日志或者直接看配置是否动态生效。这一步验证配置中心的推送链路是通的。第三步在 Sentinel 控制台给某个写好的接口加一条流控规则比如 QPS 阈值设为 1然后用 curl 连续请求几次。如果看到超出阈值的请求被拦掉说明 Sentinel 客户端、控制台和规则下发都是通的。没有现成接口的话可以临时写一个测试接口来压。第四步造一个分布式事务场景。调用一个加了GlobalTransactional的接口这个接口内部会去调用另一个服务的写库操作你在被调用的服务里故意抛一个异常回到调用方观察数据是否回滚。如果数据没回滚按前面说的排查顺序来注解、事务组名、undo_log 表。这一步验证完后一定要把测试异常代码删掉不然上线就是事故。6.2 端口和服务状态一览表最后把整套环境的服务端口整理成一张表方便以后排查。组件端口验证方式MySQL3306数据库工具连接Nacos8848另监听 9848/9849浏览器访问控制台Sentinel 控制台8858浏览器登录控制台Seata Server8091netstat -tlnp查看端口微服务网关8080访问网关健康检查接口Vue3 前端80浏览器打开页面这一套流程走下来如果每个环节都是绿的那这套 SpringCloud Nacos Sentinel Seata Vue3 的环境才算真正落地后面写业务代码才有底气。我从那以后每次搭完环境不管时间多紧都会强制把这条链路完整跑一遍尤其是 Seata 回滚那条不自己造数据测一次你永远不知道 TC 可能压根没注册进 Nacos。希望帮到你。本文还有配套的精品资源点击获取