Skip to content

07 - 电商服务架构设计 ​

本章介绍基于 Watermill + Kafka 的电商事件驱动系统的整体架构设计。

总体架构 ​

mermaid
graph LR
    subgraph "客户端"
        CURL[curl / Postman]
    end

    subgraph "API Gateway"
        OS[订单服务<br/>:8081]
    end

    subgraph "消息队列"
        K[Kafka]
    end

    subgraph "核心服务"
        IS[库存服务<br/>:8082]
        PS[支付服务<br/>:8083]
        NS[通知服务<br/>:8084]
    end

    subgraph "数据层"
        M1[(MySQL<br/>orders)]
        M2[(MySQL<br/>inventory)]
    end

    CURL -->|POST /orders| OS
    OS -->|OrderCreated| K
    K --> IS
    IS -->|InventoryReserved / InventoryInsufficient| K
    K --> PS
    PS -->|PaymentCompleted / PaymentFailed| K
    K --> OS
    K --> NS
    OS --> M1
    IS --> M2

服务拆分原则 ​

系统拆分为 4 个独立微服务,遵循**领域驱动设计(DDD)**的限界上下文原则:

服务职责端口数据存储
order-service订单创建、状态管理8081MySQL (orders 表)
inventory-service库存扣减、释放回滚8082MySQL (inventory 表)
payment-service支付处理(模拟 90% 成功率)8083无持久化(模拟)
notification-service多渠道事件通知8084无持久化(日志输出)

每个服务拥有独立数据库(Database per Service),避免共享数据库带来的耦合问题。

事件契约设计 ​

事件是服务间通信的唯一契约。本系统使用 Protobuf 定义事件 schema:

api/proto/events/v1/events.proto

Protobuf 的优势:

  • 强类型:编译期保证消息结构一致,杜绝 JSON 字段拼写错误
  • 高效序列化:体积比 JSON 小 3-10 倍,适合高吞吐场景
  • 前后兼容:字段编号而非名称匹配,平滑演进

核心事件类型清单:

事件发布者订阅者
OrderCreatedorder-serviceinventory-service, notification-service
InventoryReservedinventory-servicepayment-service
InventoryInsufficientinventory-serviceorder-service
InventoryReleasepayment-serviceinventory-service
PaymentCompletedpayment-serviceorder-service, notification-service
PaymentFailedpayment-serviceorder-service
OrderCancelledorder-servicenotification-service

所有 topic 常量和序列化工具在 ecommerce/pkg/events/events.go 中集中管理:

go
const (
    TopicOrderCreated       = "order.events"
    TopicInventoryReserved  = "inventory.events"
    TopicPaymentCompleted   = "payment.events"
    // ...
)

技术栈总结 ​

组件版本用途
Watermillv1.5事件驱动框架
watermill-kafkav3Kafka 适配器
Kafka通过 Docker Compose消息队列
GORMv2ORM
MySQL8.0数据持久化
Protobufproto3事件序列化
Viperv1YAML 配置管理
Zapv1结构化日志