跳转到内容

场景 26:外卖平台 (Food Delivery)

从一个静态菜单页面,演进到智能调度的外卖配送系统。


你想做一个外卖点餐原型,展示餐厅列表和菜单,用户可以加入购物车并模拟下单。

  • 餐厅和菜品数据用 JSON 硬编码
  • 购物车状态存 localStorage,刷新不丢失
  • 模拟下单流程(选餐→购物车→确认→“订单已提交”)
  • 基本的价格计算(单价×数量+配送费)

用 React + Tailwind 构建一个外卖点餐前端。餐厅列表和菜单用 JSON 数据硬编码。购物车存 localStorage,支持增减数量和删除。点击”下单”后显示订单确认页,计算总价(含固定配送费 5 元)。不需要后端。

  • 餐厅列表页可以点击进入菜单
  • 菜品可以加入购物车,数量可增减
  • 刷新页面购物车不丢失
  • 下单后显示订单摘要和总价
  • 配送费正确计算
  • JSON 作为静态数据源 → Module 1
  • localStorage 做客户端持久化 → Module 2
  • 购物车状态管理模式 → Module 2

V2 — 10 个用户:后端管理餐厅和订单

Section titled “V2 — 10 个用户:后端管理餐厅和订单”

餐厅老板需要管理菜单,用户订单需要持久化,配送员需要看到待配送列表。

  • 餐厅和菜品的 CRUD API
  • 订单创建和状态管理(待接单→配送中→已完成)
  • 配送员列表和订单分配
  • SQLite 存储所有数据

用 Go + Gin + GORM + SQLite 构建外卖后端。模型:Restaurant(名称、地址、分类)、MenuItem(名称、价格、描述、所属餐厅)、Order(用户、餐厅、总价、状态、配送员)、OrderItem(订单、菜品、数量)、Driver(名称、电话、状态)。订单状态:pending→accepted→delivering→completed。提供:餐厅 CRUD、下单、接单、分配配送员、完成订单的 API。

  • 餐厅和菜品可以增删改查
  • 下单后订单状态为 pending
  • 配送员可以接单,状态变为 delivering
  • 完成配送后订单状态为 completed
  • 配送员状态在空闲/配送中之间切换
  • 订单状态机设计 → Module 5
  • 多实体关联(餐厅→菜品→订单)→ Module 4
  • SQLite 快速原型 → Module 3

用户下单后想实时看到配送员位置,餐厅需要管理高峰期订单。

  • 迁移到 PostgreSQL,支持并发
  • WebSocket 推送配送员实时位置
  • 订单状态变更实时通知用户
  • 完整的订单状态机(含取消、退款)

在 V2 基础上迁移到 PostgreSQL。添加 WebSocket 端点:配送员每 5 秒上报 GPS 坐标(经纬度),服务端存入 driver_locations 表并推送给订单对应的用户。订单状态机扩展:pending→accepted→preparing→delivering→completed,任意状态可→cancelled。用户连接 WebSocket 后收到自己订单的状态变更和配送员位置更新。

  • 配送员位置通过 WebSocket 实时推送
  • 用户能看到配送员移动轨迹
  • 订单状态变更实时通知
  • 取消订单在合理状态下可用
  • PostgreSQL 正确存储位置历史
  • WebSocket 实时推送 → Module 7
  • 地理位置数据处理 → Module 6
  • 状态机扩展和约束 → Module 5

V4 — 1000 个用户:智能配送调度

Section titled “V4 — 1000 个用户:智能配送调度”

订单量增大,需要自动分配配送员,准确预估送达时间,处理并发下单。

  • 就近分配:根据配送员位置和餐厅位置自动匹配
  • 预估送达时间:出餐时间 + 配送距离/速度
  • 并发订单处理:防止同一配送员被重复分配
  • Redis 缓存热门餐厅和配送员位置

添加配送调度系统。当订单状态变为 preparing 时,自动查找 3km 内空闲配送员,按距离排序取最近的分配。用 Redis 缓存配送员实时位置(GEOADD/GEORADIUS)。预估送达时间 = 餐厅出餐时间(默认15分钟)+ 距离/平均速度(20km/h)。分配时用数据库行锁防止并发冲突。添加预估送达时间到订单响应中。

  • 空闲配送员自动分配到新订单
  • 分配优先选择最近的配送员
  • 预估送达时间合理显示
  • 并发下单不会重复分配同一配送员
  • Redis GEORADIUS 正确查询附近配送员
  • Redis GEO 命令做地理查询 → Module 8
  • 数据库锁防并发冲突 → Module 9
  • 预估算法设计 → Module 10

V5 — 1 万用户:多区域高峰应对

Section titled “V5 — 1 万用户:多区域高峰应对”

平台扩展到多个城市,午高峰订单激增,搜索需要按位置排序。

  • 按城市/区域分区运营
  • PostGIS 支持餐厅地理搜索(附近餐厅)
  • 高峰期限流:排队机制、预计等待时间
  • 订单处理异步化(消息队列)

扩展为多区域架构。餐厅表添加 PostGIS geometry 列,实现”附近 2km 餐厅”搜索 API(ST_DWithin)。添加区域配置表(城市、配送范围、配送费规则)。高峰期(订单量 > 阈值)启用排队:新订单进入 Redis 队列,按 FIFO 处理,返回排队位置。订单处理通过 goroutine worker pool 异步执行(pool size 按区域配置)。

  • 按当前位置搜索附近餐厅
  • 不同城市有独立配送费规则
  • 高峰期新订单进入排队
  • 排队位置实时更新
  • Worker pool 限制并发处理数量
  • PostGIS 地理查询 → Module 11
  • 限流和排队机制 → Module 12
  • Worker pool 模式 → Module 9

V6 — 10 万+ 用户:智能调度与动态定价

Section titled “V6 — 10 万+ 用户:智能调度与动态定价”

平台需要优化配送效率(多单合并),高峰动态调价,建立骑手画像。

  • 路线优化:同方向多单合并配送
  • 动态定价:根据供需(配送员/订单比)调整配送费
  • 骑手画像:准时率、好评率、擅长区域
  • 分库:订单库按城市分片

实现智能调度系统。多单合并:当配送员已有在途订单时,检查新订单是否顺路(两个目的地距离 < 500m 且方向偏差 < 30°),是则合并。动态定价:每分钟计算区域内(空闲配送员数 / 待分配订单数),比值 < 0.5 时配送费上浮 50%,< 0.3 时上浮 100%。骑手评分:准时率 × 0.5 + 好评率 × 0.3 + 完成量 × 0.2,优先分配高分骑手。订单表按城市 ID 做分片键,用 Citus 或应用层路由。

  • 顺路订单合并配送
  • 配送费随供需动态调整
  • 骑手评分影响派单优先级
  • 分片后跨城市查询正确
  • 合并配送路线合理(非绕路)
  • 路径优化算法基础 → Module 13
  • 动态定价策略 → Module 10
  • 数据库分片实践 → Module 14
  • 评分系统设计 → Module 10