应用参考。 这是一份示意性的架构和范围清单,并非经过验证的客户项目或实测部署。实际简报中将就技术、集成范围和交付内容达成一致。
场景与约束
某零售品牌通过微信小程序销售商品,同时经营线下门店。硬性要求是在促销期间确保各渠道库存准确:如果各渠道库存独立更新,而未预先定义预留、同步和对账规则,就会产生超卖风险。会员积分和优惠券的结算也必须保持一致,因为同一折扣若被重复应用,将直接造成财务损失。
架构
分层与职责
| 层级 | 技术 | 职责 |
|---|---|---|
| 客户端 | UniApp(使用同一套代码支持微信和抖音) | 商品目录浏览、购物车、结账和会员中心。这里不依赖任何业务规则;客户端仅呈现服务器已确认的状态。 |
| API | Go + Gin,在负载均衡器后保持无状态 | 请求验证、身份认证、业务规则和事务边界。由于进程内不保存会话状态,因此可水平扩展。 |
| 缓存 | Redis | 热门商品数据、秒杀库存计数器、分布式锁,以及支付回调的幂等键。 |
| 存储 | MySQL,配有只读副本 | 权威数据源。写入操作进入主库;当读取负载足以证明有必要时,商品目录和报表读取可路由至副本。 |
| 管理端 | Vue 3 + Element Plus | 商品、订单、库存、促销和门店管理,权限由后端强制执行。 |
| 异步处理 | 队列工作器 | 支付对账、消息推送、报表汇总、订单超时释放库存,以及所有不得阻塞结账请求的工作。 |
数据模型
以下数据表承载着其他一切所依赖的规则。设计错误会使原本可用的演示系统变成无法扩展的系统。
核心实体
| 实体 | 关键字段、关系与规则 |
|---|---|
| product / sku | 一个商品可通过属性组合对应多个 SKU。价格和库存归属于 SKU,而非商品;否则多规格定价将无法扩展。 |
| inventory | 数据行以 (sku_id, location_id) 为键,保存 on_hand 和 reserved。可用库存通过 on_hand 减去 reserved 得出;仍需通过事务和对账测试来检测差异。 |
| inventory_txn | 仅追加的账本,记录每次库存变动及其原因代码和来源订单。当前库存必须始终能够通过重放该账本重现——这使差异可审计,而非只能凭口头争论。 |
| order / order_item | 订单承载状态机和汇总信息;订单项保存购买时的 SKU 标题、规格和单价快照,防止后续修改商品目录改写订单历史。 |
| payment_txn | 网关交易 ID、金额、状态和原始回调数据。网关 ID 必须唯一,以防止重复的微信支付回调被应用两次。 |
| member / point_txn / coupon | 会员余额和积分根据仅追加的交易日志得出。优惠券记录包含适用范围、门槛、叠加优先级和 used_at 时间戳,后者用于执行单次使用限制。 |
关键接口
承载业务规则的端点
| 端点 | 用途与并发注意事项 |
|---|---|
| POST /api/v1/orders | 在单个数据库事务内创建订单并预留库存。在秒杀负载下,预留会先通过 Redis 原子递减执行,再由 MySQL 作为结算记录;客户端传入幂等键,因此连续点击不会创建两个订单。 |
| POST /api/v1/payments/callback | 网关回调。以网关交易 ID 执行幂等处理,验证签名并推进订单状态。仅在状态变更提交后返回成功,否则网关会继续重试。 |
| POST /api/v1/orders/{id}/cancel | 在关闭订单的同一事务中释放预留库存,并撤销优惠券和积分的使用。 |
| GET /api/v1/skus/{id}/availability | 通过带有较短 TTL 的缓存读取可用库存。展示的可用量会刻意存在延迟;只有订单事务具有权威效力。 |
| POST /api/v1/admin/inventory/adjust | 写入带有原因代码和操作员 ID 的 inventory_txn,而不是直接修改库存数值。每次手动更正均保持可追溯。 |
技术决策
- 采用 UniApp,而非分别开发原生小程序。 微信和抖音可共享大部分商业流程,因此一套代码可减少重复维护。平台专属的支付和登录功能被隔离在适配器层之后,而非散落在各页面中。
- 下单时预留库存,而非支付时预留。 如果在支付时才预留,客户可能已经为售出的商品付款。代价是未付款订单会占用库存,因此预留会按定时机制到期,并由工作器释放。
- 可用量采用推导方式,绝不直接存储。 缓存 available_qty 会引入另一条同步路径。推导可用量可以减少这类重复;应根据实际工作负载比较读取性能和对账行为。
- 库存、积分和余额采用仅追加账本。 任何客户可能提出异议的数字都必须能够通过日志重建,否则客服无法解释差异。
- API 层采用 Go。 工作负载是在数据库周围处理大量短时并发请求,适合 Go 的并发模型;单个静态二进制文件也能让部署和回滚保持简单。
假设性设计目标
以下数字是假设性的容量规划示例,并非实测客户结果、经验证的容量配置建议或 SLA。在确定工作负载、设备、数据、硬件和第三方依赖后,应设置项目专属验收目标;承诺生产环境目标之前,应通过试点和负载测试进行验证。
容量与性能目标
| 目标 | 数值与假设 |
|---|---|
| 商品目录读取延迟 | 假设热门数据位于 Redis 中,且数据库位于同一专用网络内,API 的 p95 延迟低于 150 ms。 |
| 订单创建 | 在单个主数据库上,订单表按 (site_id, status, created_at) 建立索引时,包含库存预留在内的 p95 延迟低于 400 ms。 |
| 秒杀突发流量 | 订单链路按每个 SKU 每分钟数千次请求进行容量规划,先通过 Redis 原子递减处理,再由 MySQL 完成结算。超出该范围后,将加入基于队列的准入控制——具体阈值需使用真实数据量进行负载测试后确认。 |
| 支付回调 | 在网关重试窗口内以幂等方式处理;根据唯一的网关交易 ID 拒绝重复回调。 |
交付内容
- 存储在您代码仓库中的小程序源码、Go 后端源码和 Vue 管理端源码
- 数据库模式、迁移、索引设计依据及账本数据表文档
- 涵盖身份认证、错误代码和幂等要求的 API 文档
- Linux、Docker 和 Nginx 的部署说明,以及备份和恢复流程
- 支付和消息账号集成支持;平台审核结果仍由微信或抖音决定
为您的业务进行规划
以上模块只是起点,并非固定套餐。我们通常会将首个版本缩减为一个核心工作流加一个管理工作流,待实际使用显示负载和边界情况所在位置后再进行扩展。提交范围明确的简报,我们会将其与此架构进行映射,并告知您目前哪些部分暂不需要。

