SWE · System / Mobile Design

Meta 订餐配送设计:订单、支付、商家与骑手状态

设计餐食下单与配送链路,拆分订单确认、支付、配餐、派单与追踪的可靠性。

题目重点:设计餐食下单与配送链路,拆分订单确认、支付、配餐、派单与追踪的可靠性。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 训练有customer/restaurant/courier三类角色,配送订单;pickup和自取可作为不同履约方式。具体库存、支付与配送时限由题面给定。
  • 订单、支付、商家履约与配送独立状态但需一致业务结果;不把一个“成功”布尔值覆盖所有阶段。

解题路线

  1. customer请求带orderRequestId,服务器校验菜品/价格版本与商家可接单状态,创建order及outbox。支付授权和商家接单按业务选择顺序,失败补偿退款/取消,不承诺跨外部服务原子事务。
  2. 状态分别记order CREATED/CONFIRMED/CANCELLED,payment AUTHORIZED/CAPTURED/REFUNDED,fulfillment PREPARING/READY,delivery ASSIGNED/PICKED_UP/DELIVERED。每事件含revision和发生证据,旧回调不能倒退终态。
  3. 派单按地点/容量/路线与接受租约筛候选,双骑手抢同job用CAS;骑手位置流用于ETA,定位更新乱序按device/session sequence处理,不等于证明送达。
  4. 客户追踪读聚合view,展示支付/商家/配送真实阶段;每服务SPOF分析多副本、持久队列与故障恢复。超时任务持久deadline可扫恢复,不能只有内存timer。
  5. 异常处理单列商家拒单/缺菜/支付timeout/骑手离线/取消时点,补偿幂等并留审计;对暂时不可用明确“待确认”,而非盲目重试多下单。

手动走一遍

支付已授权后商家拒单,需撤销授权/退款并终止派单;支付回调ACK丢失时先查询paymentId,不重复收费。两个骑手accept同deliveryVersion只有一个成功。

规模与取舍

读菜单/位置/追踪QPS可远高于订单写QPS;位置每骑手每几秒更新需另算。订单核心事务按order分片,商家热门库存写与单城派单热点不能仅靠缓存解决。

易错点与追问

容易失分的边界

  • 直接将支付成功等同订单被商家确认,会造成已付款无履约的错误体验。
  • 只说每service两个副本不能应对数据库/队列/支付依赖单点,需具体failover和数据恢复。

继续深挖

  • 取消晚于开始配餐或取餐时如何定补偿?由明确业务合同,状态机只实现已定规则。
  • 跨服务事件漏掉如何对账?基于order/payment/delivery权威记录修复聚合,不以临时pubsub当唯一事实。
✓已复制微信号!