苍穹外卖项目改造规范计划:微服务架构+nacos
一、前提背景:为什么要做微服务拆分?
1. 单体架构的核心痛点
之前项目采用单体Spring Boot架构,所有功能(用户端、管理端)耦合在一个服务中,随着业务迭代暴露以下问题:
- 资源浪费:高频功能(如购物车、下单)与低频功能(如地址簿修改)共享资源,高负载场景无法独立扩容;
- 故障扩散:一个模块异常(如购物车代码BUG)可能导致整个系统不可用;
- 迭代低效:用户端(C端)和管理端(B端)需求节奏不同(C端侧重体验,B端侧重运营),却需同步发版;
- 维护复杂:代码量持续膨胀,模块边界模糊,新功能开发、问题排查效率越来越低。
2. 拆分核心逻辑
遵循「场景+负载」双维度拆分原则:
- 高频高负载场景(如订单、购物车):独立部署,保障性能和扩容灵活性;
- 低频低负载场景(如用户地址簿、员工基础管理):聚合部署,避免资源闲置;
- 功能关联性强的场景(如商品查询类功能):集中管理,便于统一优化(如缓存、数据库操作);
- 业务域隔离(C端/B端分离):避免功能混淆,迭代互不影响。
二、微服务模块拆分方案(按业务域+负载分层)
1. 模块全景图(6个业务服务+2个公共依赖)
| 服务名称 | 业务域 | 核心功能 | 拆分原因 | 技术栈核心依赖 |
|---|---|---|---|---|
sky-cart-service |
C端-购物车 | 商品增删改、购物车清空、购物车查询 | 高频高负载,需独立扩容;与下单逻辑解耦,故障不影响核心交易 | Spring Boot、Nacos Discovery、Redis |
sky-order-service |
C端-订单 | 下单、催单、订单支付、状态变更(取消/确认/派送)、历史订单查询 | 核心交易场景,高负载+复杂逻辑;故障隔离,仅影响下单流程 | Spring Boot、Nacos Discovery、MySQL |
sky-user-base-service |
C端-用户基础 | 用户登录/登出、微信注册、地址簿管理(增删改查) | 低频场景聚合,负载低;功能关联性强,维护高效 | Spring Boot、Nacos Discovery、MySQL |
sky-user-goods-query-service |
C端-商品查询 | 套餐/菜品查询(列表/详情)、分类查询、店铺营业状态查询 | 纯查询(读多写少),集中做缓存优化;减少重复查询逻辑,降低数据库压力 | Spring Boot、Nacos Discovery、Redis |
sky-admin-order-service |
B端-管理订单 | 订单筛选、接单/拒单/派送、订单详情查询、运营数据统计 | B端高负载功能;与C端订单逻辑隔离(C端创单,B端运营) | Spring Boot、Nacos Discovery、MySQL |
sky-admin-operation-service |
B端-基础运营 | 员工管理、菜品/套餐/分类管理、店铺管理、文件上传、工作台统计 | 低负载聚合;均为平台基础运营功能,关联紧密,运维高效 | Spring Boot、Nacos Discovery、MySQL |
sky-common |
公共依赖 | 通用工具类、异常处理、常量定义、全局返回结果(Result)、JWT工具 | 统一复用,避免重复编码;规范各服务输出格式 | Spring Boot、lombok、fastjson |
sky-pojo |
公共依赖 | 所有服务共享的实体类(Entity)、DTO、VO、枚举类 | 统一数据模型,避免各服务实体不一致导致的兼容性问题 | 无(纯POJO,仅依赖lombok) |
2. 架构层级图(Mermaid语法,可直接复制渲染)
flowchart TD
subgraph 客户端层
C1[用户端APP/小程序]
C2[管理端Web后台]
end
subgraph 网关层
G[sky-server-gateway 网关统一入口]
end
subgraph 业务服务层-C端
S1[sky-cart-service 购物车服务]
S2[sky-order-service 订单服务]
S3[sky-user-base-service 用户基础服务]
S4[sky-user-goods-query-service 商品查询服务]
end
subgraph 业务服务层-B端
S5[sky-admin-order-service 管理端订单服务]
S6[sky-admin-operation-service 管理端运营服务]
end
subgraph 公共依赖层
P1[sky-common 通用工具层]
P2[sky-pojo 共享实体层]
end
subgraph 存储层
DB[MySQL 业务数据库]
R[Redis 缓存/购物车]
OSS[阿里云OSS 文件存储]
end
%% 依赖关系
C1 --> G
C2 --> G
G --> S1
G --> S2
G --> S3
G --> S4
G --> S5
G --> S6
S1 --> P1
S1 --> P2
S2 --> P1
S2 --> P2
S3 --> P1
S3 --> P2
S4 --> P1
S4 --> P2
S5 --> P1
S5 --> P2
S6 --> P1
S6 --> P2
S1 --> R
S2 --> DB
S2 --> R
S3 --> DB
S4 --> DB
S4 --> R
S5 --> DB
S6 --> DB
S6 --> OSS
3. 服务依赖关系说明
- 所有业务服务均依赖
sky-common和sky-pojo,无需重复编写通用逻辑; - 网关(
sky-server-gateway)不依赖任何业务服务,仅通过Nacos发现服务并转发请求; - 业务服务之间禁止直接依赖(如订单服务不直接调用购物车服务),需通过“服务调用+事件驱动”(后续可集成OpenFeign+RocketMQ)实现通信。
三、核心配置方案
1. 前置准备:Nacos环境初始化
(1)命名空间规划(隔离环境)
在Nacos控制台创建3个命名空间,记录ID备用:
| 命名空间名称 | 用途 | 命名空间ID(填写自己的) |
|---|---|---|
| dev | 开发环境 | 你的dev环境命名空间ID |
| test | 测试环境 | 你的test环境命名空间ID |
| prod | 生产环境 | 你的prod环境命名空间ID |
(2)分组规划(同一环境内业务隔离)
| 业务域 | 分组名称 | 包含服务 |
|---|---|---|
| C端-购物车 | sky-group-cart | sky-cart-service |
| C端-订单 | sky-group-order | sky-order-service |
| C端-用户相关 | sky-group-user | sky-user-base-service、sky-user-goods-query-service |
| B端-管理相关 | sky-group-admin | sky-admin-order-service、sky-admin-operation-service |
| 网关 | (无需单独分组) | 订阅所有业务分组 |
2. 父pom.xml(统一依赖版本,避免冲突)
项目根目录pom.xml添加依赖管理,所有服务继承此父pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sky</groupId>
<artifactId>sky-take-out</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<!-- 所有业务服务模块 -->
<module>sky-cart-service</module>
<module>sky-order-service</module>
<module>sky-user-base-service</module>
<module>sky-user-goods-query-service</module>
<module>sky-admin-order-service</module>
<module>sky-admin-operation-service</module>
<module>sky-server-gateway</module>
<!-- 公共依赖模块 -->
<module>sky-common</module>
<module>sky-pojo</module>
</modules>
<!-- 统一依赖版本管理 -->
<dependencyManagement>
<dependencies>
<!-- Spring Boot 基础版本 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.7.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Spring Cloud 版本(适配Boot 2.7.3) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Spring Cloud Alibaba 版本(适配Cloud 2021.0.4) -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2021.0.4.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 公共模块版本 -->
<dependency>
<groupId>com.sky</groupId>
<artifactId>sky-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.sky</groupId>
<artifactId>sky-pojo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</dependencyManagement>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
3. 业务服务通用配置(以sky-order-service为例)
(1)application.yml(通用配置)
spring:
application:
name: sky-order-service # 服务名(网关路由必须用此名称)
profiles:
active: ${SPRING_PROFILES_ACTIVE:dev} # 环境变量优先,默认dev
cloud:
nacos:
# Nacos服务发现配置
discovery:
server-addr: ${NACOS_SERVER_ADDR:你的Nacos地址:8848} # 本地Nacos地址,生产环境用环境变量覆盖
username: ${NACOS_USERNAME:你的Nacos用户名} # 自己的Nacos登录用户名
password: ${NACOS_PASSWORD:你的Nacos密码} # 自己的Nacos登录密码
namespace: ${NACOS_NAMESPACE:你的dev环境命名空间ID} # 填写dev环境命名空间ID
group: sky-group-order # 对应业务分组
(2)application-dev.yml(开发环境配置)
server:
port: 8082 # 每个服务端口唯一(避免冲突)
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://你的MySQL地址:3306/sky_take_out_order?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: 你的MySQL用户名
password: 你的MySQL密码
redis:
host: 你的Redis地址
port: 6379
database: 2 # 每个服务用独立的Redis数据库编号(避免key冲突)
password: 你的Redis密码(无则留空)
timeout: 3000ms
4. 网关配置(sky-server-gateway)
(1)pom.xml(核心依赖)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.sky</groupId>
<artifactId>sky-take-out</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.sky</groupId>
<artifactId>sky-server-gateway</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- Gateway核心依赖(WebFlux,禁止加spring-boot-starter-web) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- Nacos服务发现 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 负载均衡组件(lb://协议必须) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-- 公共模块 -->
<dependency>
<groupId>com.sky</groupId>
<artifactId>sky-common</artifactId>
</dependency>
<dependency>
<groupId>com.sky</groupId>
<artifactId>sky-pojo</artifactId>
</dependency>
</dependencies>
</project>
(2)application.yml(路由规则+Nacos配置)
spring:
application:
name: sky-server-gateway
profiles:
active: ${SPRING_PROFILES_ACTIVE:dev}
cloud:
nacos:
discovery:
server-addr: ${NACOS_SERVER_ADDR:你的Nacos地址:8848}
username: ${NACOS_USERNAME:你的Nacos用户名}
password: ${NACOS_PASSWORD:你的Nacos密码}
namespace: ${NACOS_NAMESPACE:你的dev环境命名空间ID}
# 网关订阅所有业务分组(逗号分隔)
group: sky-group-cart,sky-group-order,sky-group-user,sky-group-admin
gateway:
# 路由规则(按业务域划分)
routes:
# 1. C端-购物车路由
- id: cart-service-route
uri: lb://sky-cart-service # 对应购物车服务名
predicates:
- Path=/api/cart/** # 前端请求路径前缀
filters:
- StripPrefix=1 # 去掉前缀/api,转发到/cart/**
# 2. C端-订单路由
- id: order-service-route
uri: lb://sky-order-service
predicates:
- Path=/api/order/**
filters:
- StripPrefix=1
# 3. C端-用户基础路由
- id: user-base-service-route
uri: lb://sky-user-base-service
predicates:
- Path=/api/user/**
filters:
- StripPrefix=1
# 4. C端-商品查询路由
- id: goods-query-service-route
uri: lb://sky-user-goods-query-service
predicates:
- Path=/api/goods/**
filters:
- StripPrefix=1
# 5. B端-管理订单路由
- id: admin-order-service-route
uri: lb://sky-admin-order-service
predicates:
- Path=/admin/order/**
filters:
- StripPrefix=1
# 6. B端-基础运营路由
- id: admin-operation-service-route
uri: lb://sky-admin-operation-service
predicates:
- Path=/admin/** # 运营后台请求前缀(与其他路由不冲突)
(3)启动类(com.sky.gateway.SkyGatewayApplication)
package com.sky.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* 网关启动类:排除Redis自动配置(网关无需直接操作Redis)
* 禁止添加@EnableWebMvc(与WebFlux冲突)
*/
@SpringBootApplication(exclude = {RedisAutoConfiguration.class})
@EnableDiscoveryClient
public class SkyGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(SkyGatewayApplication.class, args);
}
}
5. 公共模块配置(sky-common示例)
pom.xml(核心依赖)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.sky</groupId>
<artifactId>sky-take-out</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.sky</groupId>
<artifactId>sky-common</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- Spring Boot基础依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- 工具类 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
<!-- JWT工具 -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!-- 异常处理 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>provided</scope> <!-- 仅提供编译支持,避免与网关WebFlux冲突 -->
</dependency>
</dependencies>
</project>
四、避坑指南:避免“服务找不到”“配置冲突”的核心原则
- Nacos隔离三要素:所有服务(含网关)必须满足「同一命名空间+网关订阅对应分组+服务名完全一致」,否则服务不可见;
- 端口唯一:每个业务服务的
server.port必须不同(如购物车8081、订单8082、用户基础8083),避免端口占用; - 依赖冲突:网关禁止引入
spring-boot-starter-web(与WebFlux冲突),业务服务按需引入; - Redis数据库隔离:不同服务使用不同的Redis
database编号(如购物车用1、订单用2),避免key覆盖; - 启动顺序:必须按「Nacos → 公共模块(install到本地仓库) → 业务服务 → 网关」启动,否则网关启动时找不到业务服务。
五、方案优势与后续扩展
1. 方案优势
- 可扩展性:高负载服务(如订单、购物车)支持独立扩容,应对流量峰值;
- 稳定性:故障隔离,单个服务异常不影响全局;
- 维护性:业务域边界清晰,迭代高效,新功能可快速新增服务(如后续新增支付服务
sky-payment-service); - 通用性:配置方案标准化,新增服务可直接复制现有模板修改。
2. 后续扩展方向
- 服务通信:集成OpenFeign实现服务间同步调用(如订单服务调用购物车服务清空数据);
- 分布式事务:引入Seata解决跨服务事务问题(如订单创建+库存扣减);
- 熔断降级:集成Sentinel避免服务雪崩(如高并发下保护订单服务);
- 监控告警:集成Prometheus+Grafana监控服务状态,配置告警规则。
总结
本方案基于「业务域+负载」双维度拆分微服务,通过Nacos的「命名空间+分组」实现环境隔离与业务隔离,网关统一入口转发请求,既解决了单体架构的痛点,又保障了微服务的可扩展性和稳定性。所有配置均已替换为占位符,无任何敏感信息,复制粘贴后只需填入自己的环境信息(Nacos地址、数据库密码等)即可快速落地,后续新增服务遵循此规范即可无缝集成。

浙公网安备 33010602011771号