商城系统开发(一):电商系统架构设计

支付系统基本稳定了,下一个目标是搭建一套商城系统。不是要造淘宝,而是做一个能跑通完整电商流程的中小型系统,既是练手也是真要用。这篇先把架构理清楚。

为什么要自己做

市面上开源商城不少(mall、litemall等),但:

  • 大部分是Java单体,我想用Go练手
  • 很多开源项目代码质量参差不齐,二次开发成本不低
  • 自己做一遍才能真正理解电商系统的复杂度

目标:一个人能维护的、功能完整的电商系统。不追求高并发(先跑通再说),但架构上要留好扩展空间。

领域模型

电商系统的核心领域:

商品域

  • SPU(Standard Product Unit):标准产品单元,比如"iPhone 15"
  • SKU(Stock Keeping Unit):库存量单位,比如"iPhone 15 蓝色 256G"
  • 商品分类(多级)、品牌、商品属性(规格参数)
  • 商品图片、详情(富文本)

订单域

  • 订单(Order) -> 订单项(OrderItem)
  • 订单状态机:待付款 -> 已付款 -> 已发货 -> 已收货 -> 已完成
  • 取消、退款、售后是反向流程
  • 订单号生成:时间戳+机器ID+序列号,确保全局唯一

支付域

  • 已经做好了,直接对接上一个项目的支付网关
  • 支付单和订单是一对一关系(简化处理,暂不支持合并支付)

库存域

  • SKU维度的库存管理
  • 下单时预扣库存(避免超卖),支付成功后确认扣减,超时未支付则释放
  • 库存不做独立服务,放在商品服务里

用户域

  • 注册/登录(手机号+验证码)
  • 收货地址管理
  • 用户等级(暂时简单做)

营销域

  • 优惠券(满减、折扣)
  • 限时特价
  • 这块先留接口,后面慢慢加

微服务 vs 单体

一个人的项目,上微服务是自找麻烦吗?我的选择是模块化单体,为微服务做好准备

具体来说:

  • 代码按领域分模块,模块之间通过接口调用,不直接访问对方的数据库表
  • 所有模块共享一个进程,部署简单
  • 每个模块有自己的数据库schema(逻辑隔离)
  • 如果后面某个模块需要独立扩展,拆出去改成gRPC调用就行

这个思路参考了Shopify早期的架构——他们也是从单体开始,随着业务增长逐步拆分。

技术选型

组件 选择 理由
语言 Go 1.20 练手 + 部署简单 + 性能好
Web框架 Gin 生态好,中间件丰富
RPC gRPC + protobuf 为未来拆分准备
数据库 PostgreSQL 15 JSON字段存商品属性很方便
缓存 Redis 7 会话、购物车、库存预扣
搜索 Elasticsearch 8 商品搜索
消息队列 Kafka 订单事件、库存同步
对象存储 MinIO 商品图片,兼容S3 API
容器 Docker Compose 本地开发一键启动

Go没有Spring那套成熟的生态,很多东西要自己组装。选Wire做依赖注入(下篇会写)。ORM用sqlc——直接写SQL,编译时生成Go代码,比GORM靠谱。

核心架构

                    +----------------+
                    |     Nginx      |
                    |   (反向代理)    |
                    +-------+--------+
                            |
              +-------------+-------------+
              |                           |
     +--------v--------+    +------------v----------+
     |  商城前端(Vue3)  |    |  管理后台(Vue3)       |
     +--------+---------+    +------------+----------+
              |                           |
              +-------------+-------------+
                            |
                    +-------v--------+
                    |   API网关      |
                    |  (Gin路由)     |
                    +-------+--------+
                            |
        +-------------------+-------------------+
        |                   |                   |
  +-----v-----+    +-------v-------+   +-------v-------+
  | 商品模块  |    |  订单模块     |   |  用户模块     |
  | Product   |    |  Order        |   |  User         |
  +-----+-----+    +-------+-------+   +-------+-------+
        |                  |                    |
        |           +------v-------+            |
        |           |  支付模块    |            |
        |           |  Payment     |            |
        |           +--------------+            |
        |                                       |
  +-----v---------------------------------------v------+
  |             PostgreSQL (schema隔离)                 |
  +----+----------+----------+-----------+-------------+
  | product  |  order   |  payment  |  user            |
  +----------+----------+-----------+------------------+

数据库设计要点

  • 金额全部用BIGINT存储(单位:分),不用DECIMAL避免浮点问题
  • 商品属性用PostgreSQL的JSONB字段,查询灵活
  • 订单表做分表预留:订单号包含时间信息,后续按月分表
  • 所有表加created_atupdated_atdeleted_at(软删除)

项目结构

mall/
├── cmd/
│   └── server/          # 入口
├── internal/
│   ├── product/         # 商品模块
│   │   ├── handler/     # HTTP handler
│   │   ├── service/     # 业务逻辑
│   │   ├── repo/        # 数据访问
│   │   └── model/       # 数据模型
│   ├── order/           # 订单模块
│   ├── payment/         # 支付模块
│   ├── user/            # 用户模块
│   └── marketing/       # 营销模块(预留)
├── pkg/
│   ├── middleware/       # 通用中间件
│   ├── auth/            # JWT认证
│   └── response/        # 统一响应格式
├── api/
│   └── proto/           # protobuf定义
├── configs/
├── migrations/          # 数据库迁移
├── docker-compose.yml
└── Makefile

开发计划

  1. 第一阶段(2周):项目骨架搭建,用户注册登录,商品CRUD
  2. 第二阶段(2周):购物车、下单流程、库存扣减
  3. 第三阶段(1周):对接支付系统,完成支付流程
  4. 第四阶段(2周):商品搜索(ES)、前端页面
  5. 第五阶段(持续):营销功能、性能优化

先做后端API,前端用Vue3 + Element Plus快速搭。

下一篇先把Go的依赖注入搞定(Wire),这是整个项目的基础设施。