Skip to content

技术架构 ​

功能分层见 开发指南。本篇说明进程如何部署:同一套后端源码可以运行在一个进程(单体),或拆成网关 + 多个服务(微服务)。对外端口都是 48080,前缀仍是 /admin-api、/app-api。日常开发使用单体。

名称说明仓库路径
单体只启动一个 yudao-server,所有业务模块在同一个进程里编译或 IDEA 运行时选 boot
微服务先启动网关,再启动各个 *-server编译或 IDEA 运行时选 cloud(默认选项)
yudao-server单体部署时的后端进程ruoyi-office/yudao-server/
yudao-gateway微服务入口,端口 48080ruoyi-office/yudao-gateway/
Nacos微服务的注册中心与配置中心;单体默认关闭yudao-server 的 application.yaml

示意图:同一套模块,两种部署方式。浏览器只访问 48080。

两种形态的联系 ​

对照两张图时,先看两边对齐的部分。这些不随单体或微服务改变。

层两种形态相同
前端电脑 / 手机 → 管理后台 Vben、管理后台 UniApp、用户前端 UniApp
接入Nginx 反代 HTTP
存储MySQL、Redis、OSS / MinIO;需要搜索时再接入 Elasticsearch
中间件XXL-Job 调度、RocketMQ 收发
运维 / 监控Jenkins、Docker、Portainer、SBA、Druid、SkyWalking

模块源码也是同一份:yudao-module-*-api + *-server。变化的是进程数量,以及模块之间如何调用。

单体技术架构 ​

本机开发与小规模交付采用单体。Nginx 将请求反向代理到同一个 yudao-server :48080。system / infra / 业务模块运行在同一进程,模块间调用走本地 ApiImpl,不必先启动 Nacos。

单体技术架构

单体:后端集中在同一进程。上方为 XXL-Job、RocketMQ、Redisson。

yudao-server 是空壳:pom.xml 声明要装哪些 yudao-module-xxx-server,启动类扫 cn.iocoder.yudao.module。裁模块改依赖,不是改扫描包。

名称说明仓库路径
启动类YudaoServerApplicationruoyi-office/yudao-server/.../YudaoServerApplication.java
端口 / 应用名48080 / yudao-serverapplication-local.yaml、application.yaml
Nacosdiscovery / config 都是 enabled: false同文件 spring.cloud.nacos
OpenFeign依赖里排除,模块间走本地 Beanyudao-server/pom.xml 对 yudao-spring-boot-starter-rpc 的 exclusion
锁Redisson,图上「获取锁」yudao-spring-boot-starter-protection / Redis

本机以单体方式启动:在 IDEA 的 Maven 面板勾选 boot(不要使用默认的 cloud),再运行 YudaoServerApplication。命令行等价于:

powershell
cd ruoyi-office
mvn -P boot -DskipTests compile

前端代理仍指向 http://127.0.0.1:48080/admin-api。

工具默认按微服务打包

IDEA / Maven 如果没改成 boot,会按微服务方式打各个模块,端口对不上单体。

微服务技术架构 ​

需要按服务独立扩容时采用微服务。Nginx 将请求负载均衡到 Gateway,Gateway 再按路径转发到 system-server / infra-server / 业务 *-server。

微服务技术架构

微服务:中间多一列 Gateway,业务按进程拆开。

图上方的 Seata、Nacos、Sentinel 是可接拓扑。本仓库默认:微服务才用 Nacos;没有成套 Seata / Sentinel。跨库一致性自己收口(本地消息、幂等、对账)。限流、幂等、锁在 yudao-spring-boot-starter-protection。

名称说明仓库路径
网关GatewayServerApplication,gateway-server,:48080ruoyi-office/yudao-gateway/
systemsystem-server,:48081yudao-module-system/yudao-module-system-server/
infrainfra-server,:48082yudao-module-infra/yudao-module-infra-server/
bpmbpm-server,:48083yudao-module-bpm/yudao-module-bpm-server/
oaoa-server,:48106yudao-module-oa/yudao-module-oa-server/
其它模块各自 server.port对应 yudao-module-*-server

进程名必须等于 spring.application.name,也必须等于 *-api 里 @FeignClient 的 name。Nacos 本机默认 127.0.0.1:8848,命名空间 dev:

yaml
spring:
  config:
    import:
      - optional:classpath:application-${spring.profiles.active}.yaml
      - optional:nacos:${spring.application.name}-${spring.profiles.active}.yaml

缺 Nacos 时本地 yaml 仍能启动,注册、发现、动态路由会空。

差异与决策 ​

看什么单体微服务
进程一个 yudao-server :48080Gateway :48080 + 各 *-server
模块间调用同 JVM,本地 ApiImplFeign,注册名 = spring.application.name
注册 / 配置关闭 NacosNacos
额外组件Redisson 分布式锁Gateway;Seata / Sentinel 为可选项
定时任务一个执行器各进程自己的 xxl.job.executor.appname

本机开发接口、联调单据、调试定时任务:使用单体。需要按域扩容、多实例灰度、团队分别启动服务:使用微服务。本机开发不必同时启动全部 *ServerApplication。

请求如何进入 ​

网关按路径将 /admin-api/{module}/**、/app-api/{module}/** 转发到对应服务。文档路径再 RewritePath 为服务根路径上的 /v3/api-docs。浏览器、App、/doc.html 均访问 48080。48081、48106 仅供进程监听和本机断点。

名称说明仓库路径
路由表spring.cloud.gateway.server.webflux.routesruoyi-office/yudao-gateway/src/main/resources/application.yaml
认证有 Token 则调 system 校验,写入 login-user 头;没有 Token 也放行,登录校验仍在业务服务.../filter/security/TokenAuthenticationFilter.java
访问日志方法、路径、耗时、trace.../filter/logging/AccessLogFilter.java
跨域全局 CORS.../filter/cors/CorsFilter.java
动态路由改 Nacos 里 gateway-server.yaml.../route/dynamic/package-info.java
文档聚合Knife4j Gateway同 yaml 的 knife4j.gateway
yaml
- id: system-admin-api
  uri: grayLb://system-server
  predicates:
    - Path=/admin-api/system/**
  filters:
    - RewritePath=/admin-api/system/v3/api-docs, /v3/api-docs

新加可独立部署的模块:给 *-server 配 spring.application.name 和端口,再在网关加 Path 和 Knife4j 分组。细节见 接口文档、新建服务。

网关校验 Token 用 WebClient + 负载均衡,不走 OpenFeign(WebFlux 下没有现成的 Reactive Feign)。Token 过期或校验失败时仍转发,由下游决定 401。

模块间如何调用 ​

契约在 *-api,实现在 *-server。微服务通过 OpenFeign 按服务名调用;单体在同一进程内直接注入 *ApiImpl。

名称说明仓库路径
RPC 前缀/rpc-apiyudao-framework/yudao-common/.../RpcConstants.java
服务名与 spring.application.name 一致,如 system-server例如 yudao-module-system-api/.../ApiConstants.java
接口@FeignClient + @GetMapping(PREFIX + "/get"),返回 CommonResult<T>例如 AdminUserApi
实现@RestController 实现同一接口例如 AdminUserApiImpl
放行各模块 Security 对 ApiConstants.PREFIX + "/**" permitAll例如 system 的 SecurityConfiguration
用户 / 租户透传Feign 带 login-user、租户号LoginUserRequestInterceptor、TenantRequestInterceptor
可选模块仅 Nacos 发现打开时才注册 Feign例如 OaAssetRpcConfiguration
java
@FeignClient(name = ApiConstants.NAME, contextId = "adminUserApi")
public interface AdminUserApi {

    String PREFIX = ApiConstants.PREFIX + "/user";

    @GetMapping(PREFIX + "/get")
    CommonResult<AdminUserRespDTO> getUser(@RequestParam("id") Long id);
}

ApiConstants.NAME 是 system-server,PREFIX 是 /rpc-api/system。实现类:yudao-module-system-server/.../api/user/AdminUserApiImpl.java。消费者在自己的 RpcConfiguration 里 @EnableFeignClients(clients = {AdminUserApi.class, ...}),不要扫对方 *-server 的内部类。

定时任务在微服务里落在各自进程的执行器上,xxl.job.executor.appname 用 ${spring.application.name}。写法见 定时任务 XXL-Job。

本机联调 ​

共享环境已有一套微服务时,本机只启动正在修改的服务,通过环境标签将请求转发到本机。

名称说明仓库路径
标签yudao.env.tag,写入 Nacos 实例 metadata.tagyudao-spring-boot-starter-env/.../EnvProperties.java
请求头tag;值为 ${HOSTNAME} 时网关换成本机主机名yudao-gateway/.../util/EnvUtils.java
灰度 URIgrayLb://system-server,不是 lb://网关 application.yaml
负载均衡先按 version,再按 tag 滤实例.../filter/grey/GrayLoadBalancer.java
Feign 透传调用下游时带上当前 tag.../env/core/fegin/EnvRequestInterceptor.java

顺序:Nacos 已起 → 启动 GatewayServerApplication(占 48080)→ 启动正在改的 *ServerApplication → 实例加上 yudao.env.tag → 浏览器或 Knife4j 带 tag。

没有 tag 时,网关优先选择同样不带 tag 的实例,避免把演示环境的请求转发到本机。标签不匹配时回退到全部实例,日志中会有警告。version 请求头对应实例 metadata.version(system 本地一般为 1.0.0)。

配置 ​

没有「微服务」菜单。改打包方式后要重新启动,页面上没有这个开关。模块怎么拆、Admin / App 为什么分开,见 项目结构。

相关篇 ​

联系我们

获取报价、演示和二开方案

微信咨询二维码

微信咨询

17156169080

添加时备注「RuoYi Office」

在线体验商业版