电商微服务架构设计
本文以电商平台为业务场景,从 0 到 1 设计一套基于 Spring Cloud 的生产级微服务架构,涵盖服务拆分、技术选型、调用链路、部署拓扑等全链路设计。
一、业务背景
假设我们要构建一个中型电商平台,核心业务流程如下:
用户注册 → 浏览商品 → 加入购物车 → 下单 → 扣减库存 → 支付 → 发货 → 确认收货日均订单量:10 万单,峰值 QPS(秒杀场景):5000+
二、服务拆分
按照领域驱动设计(DDD)的限界上下文原则,将系统拆分为以下微服务:
┌──────────────────────────────────────────────────────────────────────────────┐
│ 电商平台微服务架构 │
│ │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ 业务服务层 │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ 用户服务 │ │ 商品服务 │ │ 订单服务 │ │ 支付服务 │ │ 物流服务 │ │ │
│ │ │ │ │ │ │ │ │ │ │ │ │ │
│ │ │ • 注册 │ │ • 商品CRUD│ │ • 下单 │ │ • 支付 │ │ • 发货 │ │ │
│ │ │ • 登录 │ │ • 分类 │ │ • 查单 │ │ • 退款 │ │ • 物流追踪│ │ │
│ │ │ • 地址 │ │ • 搜索 │ │ • 取消 │ │ • 对账 │ │ • 签收 │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ 购物车 │ │ 库存服务 │ │ 营销服务 │ │ 通知服务 │ │ │
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ • 加购 │ │ • 扣库存 │ │ • 优惠券 │ │ • 短信 │ │ │
│ │ │ • 删除 │ │ • 回库存 │ │ • 秒杀 │ │ • 邮件 │ │ │
│ │ │ • 合并 │ │ • 查询 │ │ • 满减 │ │ • 推送 │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ 基础设施层 │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ Nacos │ │ Gateway │ │ Sentinel │ │ Sleuth + │ │ │
│ │ │ 注册+配置 │ │ API网关 │ │ 流量治理 │ │ SkyWalking│ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ 数据存储层 │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ MySQL │ │ Redis │ │RocketMQ │ │Elasticsearch│ │ │
│ │ │ 业务数据 │ │ 缓存/锁 │ │ 消息队列 │ │ 商品搜索 │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────────┘三、技术选型
| 层级 | 技术 | 选型理由 |
|---|---|---|
| 注册中心 | Nacos 2.x | 注册+配置双合一,阿里生产验证,AP/CP 可切换 |
| 配置中心 | Nacos Config | 同上,避免引入额外组件 |
| API 网关 | Spring Cloud Gateway | 基于 Netty 非阻塞,性能优秀,Spring 官方推荐 |
| 服务调用 | OpenFeign + LoadBalancer | 声明式调用,客户端负载均衡,与 Spring 生态完美集成 |
| 熔断限流 | Sentinel | 比 Hystrix 更强大,支持控制台可视化,规则持久化 |
| 链路追踪 | Micrometer Tracing + SkyWalking | Java Agent 无侵入,国产 APM,中文社区活跃 |
| 消息队列 | RocketMQ | 事务消息、顺序消息,适合电商场景 |
| 缓存 | Redis Cluster | 热点数据缓存,分布式锁,令牌桶限流 |
| 数据库 | MySQL 8.0 + ShardingSphere | 分库分表,读写分离 |
| 搜索引擎 | Elasticsearch | 商品全文搜索 |
| 对象存储 | MinIO / 阿里云 OSS | 商品图片、用户头像 |
| 容器编排 | Kubernetes | 服务编排,弹性伸缩 |
| CI/CD | Jenkins + Docker | 自动化构建、测试、部署 |
四、核心业务调用链路
4.1 下单流程(核心链路)
用户点击"立即购买"
│
▼
┌──────────────────────────────────────────────────────────────────────────────┐
│ Gateway 网关 │
│ ├── 鉴权:校验 JWT Token,解析 userId │
│ ├── 限流:下单接口 QPS 限制(1000/s) │
│ └── 路由:/api/order/create → order-service │
└──────────────────────────────────┬───────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────────────────┐
│ order-service (订单服务) │
│ │
│ 1. 参数校验:收货地址、商品列表 │
│ 2. 查询商品信息 │
│ ├── Feign → product-service.getProductList(productIds) [同步] │
│ └── 计算订单总金额 │
│ 3. 预扣库存 │
│ ├── Feign → inventory-service.lockStock(productId, quantity) [同步] │
│ └── Sentinel 熔断保护:库存服务挂了则降级返回"库存服务繁忙" │
│ 4. 创建订单(状态:待支付) │
│ └── INSERT INTO orders ... │
│ 5. 创建支付单 │
│ ├── Feign → payment-service.createPayment(orderId, amount) [同步] │
│ └── 返回支付链接 │
│ 6. 发送订单创建事件 │
│ └── RocketMQ → topic: order-created [异步] │
│ │
│ 整个链路 TraceId: a1b2c3d4-xxxx,贯穿所有服务 │
└──────────────────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────────────────┐
│ 异步处理(消费者) │
│ │
│ notification-service 消费 order-created: │
│ └── 发送下单成功短信 │
│ │
│ marketing-service 消费 order-created: │
│ └── 发放新用户优惠券 │
└──────────────────────────────────────────────────────────────────────────────┘4.2 秒杀场景(特殊链路)
┌──────────────────────────────────────────────────────────────────────────────┐
│ 秒杀流量防护体系 │
│ │
│ 用户请求 │
│ │ │
│ ▼ │
│ ┌──────────────────┐ │
│ │ 第一道防线:Gateway│ ← 全局 QPS 限流,直接拒绝超额请求 │
│ │ RequestRateLimiter │ │
│ └────────┬─────────┘ │
│ │ 通过的请求 │
│ ▼ │
│ ┌──────────────────┐ │
│ │ 第二道防线:Redis │ ← 预扣库存,库存为 0 直接返回"已售罄" │
│ │ 库存预扣 (Lua) │ │
│ └────────┬─────────┘ │
│ │ 扣减成功 │
│ ▼ │
│ ┌──────────────────┐ │
│ │ 第三道防线:MQ 削峰 │ ← 写入 RocketMQ,异步处理,避免后端被打垮 │
│ │ 秒杀订单队列 │ │
│ └────────┬─────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────┐ │
│ │ 第四道防线:Sentinel│ ← 消费端限流,控制处理速度,保护数据库 │
│ │ 消费端限流 │ │
│ └────────┬─────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────┐ │
│ │ 订单服务消费处理 │ ← 创建订单,扣减真实库存 │
│ └──────────────────┘ │
└──────────────────────────────────────────────────────────────────────────────┘五、数据库设计
5.1 数据库 per 服务
每个服务拥有独立的数据库,服务间不能直接访问对方的数据库:
user-service → MySQL: db_user (用户表、地址表)
product-service → MySQL: db_product (商品表、分类表、SKU 表)
order-service → MySQL: db_order (订单表、订单明细表)
payment-service → MySQL: db_payment (支付单表、退款单表)
inventory-service → MySQL: db_inventory (库存表、库存流水表)
cart-service → Redis (购物车数据,TTL 过期)5.2 分布式事务方案
下单涉及多个服务,需要保证数据最终一致性:
下单流程事务方案:
order-service ──创建订单──→ 本地事务(订单状态:待支付)
│
inventory-service ──扣库存──→ 本地事务(库存扣减 + 库存流水)
│
payment-service ──创建支付单──→ 本地事务(支付单创建)
方案:Seata AT 模式
- 一阶段:各服务执行本地事务,Seata 自动生成 undo log
- 二阶段:全部成功则提交,任一失败则回滚(通过 undo log 补偿)
- 如果 Seata 故障,还有 RocketMQ 事务消息做兜底(最终一致性)六、部署架构
┌──────────────────────────────────────────────────────────────────────────────┐
│ Kubernetes 集群拓扑 │
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ Ingress (Nginx) │ │
│ │ 域名路由 + SSL 卸载 │ │
│ └──────────────────────────────┬─────────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────────▼─────────────────────────────────────────┐ │
│ │ Gateway 集群 (3 副本) │ │
│ │ gateway-1 │ gateway-2 │ gateway-3 │ │
│ └──────────────────────────────┬─────────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────────▼─────────────────────────────────────────┐ │
│ │ 业务服务集群 │ │
│ │ │ │
│ │ order-service user-service product-service payment-service │ │
│ │ (3 副本) (2 副本) (2 副本) (3 副本) │ │
│ │ │ │
│ │ inventory-svc cart-service notification-svc marketing-svc │ │
│ │ (3 副本) (2 副本) (2 副本) (2 副本) │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ 基础设施集群 │ │
│ │ │ │
│ │ Nacos 集群 Sentinel SkyWalking RocketMQ Redis Cluster │ │
│ │ (3 节点) Dashboard OAP Server (2 主2从) (3 主3 从) │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ 数据存储集群 │ │
│ │ │ │
│ │ MySQL 主从 Elasticsearch MinIO Prometheus Grafana │ │
│ │ (1 主 2 从) (3 节点) (集群) (监控) (可视化) │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────────┘七、项目结构
ecommerce-platform/
├── ecommerce-gateway/ # API 网关
│ ├── src/main/java/...
│ └── pom.xml
├── ecommerce-common/ # 公共模块(DTO、工具类)
├── ecommerce-user/ # 用户服务
│ ├── user-api/ # Feign 接口定义(给其他服务用)
│ └── user-service/ # 服务实现
├── ecommerce-product/ # 商品服务
├── ecommerce-order/ # 订单服务
├── ecommerce-payment/ # 支付服务
├── ecommerce-inventory/ # 库存服务
├── ecommerce-cart/ # 购物车服务
├── ecommerce-notification/ # 通知服务
├── ecommerce-marketing/ # 营销服务
├── docker-compose/ # 本地开发环境
│ ├── docker-compose.yml # Nacos、MySQL、Redis、RocketMQ 等
│ └── k8s/ # Kubernetes 部署文件
│ ├── gateway-deployment.yaml
│ ├── order-service-deployment.yaml
│ └── ...
└── docs/ # 架构文档八、关键设计决策
| 决策 | 方案 | 原因 |
|---|---|---|
| 服务间通信 | Feign(同步) + RocketMQ(异步) | 查询类走同步,通知类走异步,分离关注点 |
| 分布式事务 | Seata AT + RocketMQ 事务消息兜底 | Seata 处理大多数场景,MQ 兜底保证最终一致性 |
| 购物车存储 | Redis(TTL 7 天) | 高频读写,MySQL 扛不住,Redis 天然适合 |
| 商品搜索 | Elasticsearch | 全文搜索、分词、高亮、聚合,MySQL 做不到 |
| 秒杀库存扣减 | Redis Lua 预扣 + MQ 异步 | 极致性能,先扣 Redis,再异步同步到 MySQL |
| 服务部署 | Kubernetes + HPA | 弹性伸缩,根据 CPU/内存自动扩缩容 |