1. 项目背景与核心需求
"苍穹外卖"这个项目名称听起来像是一个外卖配送系统的开发实践。Day02的编号方式暗示这是一个系列教程或开发日志的第二部分,通常这类内容会聚焦于某个特定功能模块的实现或技术难点的突破。
从行业经验来看,外卖系统开发第二天通常会涉及以下核心模块:
- 用户端功能完善(如购物车、地址管理)
- 商家后台功能开发(如菜品管理)
- 骑手接单系统搭建
- 订单状态机设计
- 基础架构优化(如缓存策略)
2. 技术架构选型分析
2.1 现代外卖系统典型架构
一个完整的外卖平台通常采用微服务架构,包含以下核心服务:
- 用户服务(账户、权限、个人中心)
- 商家服务(门店管理、菜品管理)
- 订单服务(状态流转、支付对接)
- 配送服务(路线规划、骑手调度)
- 评价服务(评分系统、投诉处理)
2.2 数据库设计要点
外卖系统的数据库设计有几个关键考量:
- 订单表需要特殊设计(包含用户ID、商家ID、骑手ID的三方关联)
- 菜品表要考虑规格属性(如辣度、份量等可选参数)
- 地址信息需要支持GIS坐标存储
- 需要设计合理的冗余字段减少联表查询
sql复制-- 典型订单表示例
CREATE TABLE orders (
id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL,
shop_id BIGINT NOT NULL,
rider_id BIGINT,
status TINYINT NOT NULL COMMENT '0-待支付 1-已接单 2-配送中 3-已完成 4-已取消',
total_amount DECIMAL(10,2) NOT NULL,
actual_amount DECIMAL(10,2) NOT NULL,
address_json JSON NOT NULL COMMENT '收货地址快照',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_user (user_id),
INDEX idx_shop (shop_id),
INDEX idx_rider (rider_id)
);
3. Day02可能涉及的核心开发内容
3.1 购物车模块实现
购物车是外卖系统的核心交互模块,需要处理:
- 多商家商品合并计算
- 实时价格校验(防止商家调价导致的差异)
- 优惠券可用性检查
- 库存预占机制
前端实现要点:
javascript复制// Vue3购物车实现示例
const cartStore = reactive({
items: [],
selectedShop: null,
get total() {
return this.items.reduce((sum, item) => sum + item.price * item.quantity, 0)
},
async refreshPrices() {
const res = await api.post('/cart/validate', { items: this.items })
this.items = res.data.validatedItems
}
})
3.2 订单状态机设计
外卖订单有复杂的生命周期,典型状态包括:
- 待支付(15分钟超时)
- 待接单(商家可操作)
- 制作中(商家确认)
- 待配送(骑手可见)
- 配送中
- 已完成
- 已取消(多取消原因)
状态机实现建议:
java复制// 订单状态枚举示例
public enum OrderStatus {
PENDING_PAYMENT(1, "待支付") {
@Override
public boolean canChangeTo(OrderStatus newStatus) {
return newStatus == PAID || newStatus == CANCELLED;
}
},
// 其他状态定义...
private final int code;
private final String desc;
public abstract boolean canChangeTo(OrderStatus newStatus);
}
4. 性能优化关键点
4.1 高并发下单处理
外卖系统需要应对用餐高峰期的流量冲击:
- 使用Redis预减库存避免超卖
- 订单号生成使用雪花算法
- 异步处理非核心流程(如短信通知)
- 本地缓存商家信息减少DB查询
go复制// Go语言库存扣减示例
func ReduceStock(ctx context.Context, productID int64, num int) error {
redisKey := fmt.Sprintf("stock:%d", productID)
// Lua脚本保证原子性
script := `
local stock = tonumber(redis.call('GET', KEYS[1]))
if stock >= tonumber(ARGV[1]) then
return redis.call('DECRBY', KEYS[1], ARGV[1])
else
return -1
end`
result, err := redis.NewScript(script).Run(ctx,
rdb, []string{redisKey}, num).Int()
if err != nil || result < 0 {
return errors.New("库存不足")
}
return nil
}
4.2 地理围栏实现
配送范围检查是基础功能:
- 使用MongoDB的地理空间索引
- 射线法判断点是否在多边形内
- 缓存商家配送区域减少计算压力
python复制# Python地理围栏检查示例
from shapely.geometry import Point, Polygon
def check_delivery_range(shop_id, lng, lat):
# 从缓存获取商家配送区域
delivery_area = cache.get(f'shop:area:{shop_id}')
if not delivery_area:
delivery_area = db.query_polygon(shop_id)
cache.set(f'shop:area:{shop_id}', delivery_area)
point = Point(lng, lat)
polygon = Polygon(delivery_area['coordinates'])
return polygon.contains(point)
5. 异常处理与监控
5.1 典型异常场景
外卖系统需要特别注意:
- 支付成功但订单状态未更新
- 骑手接单超时后的自动改派
- 商家接单超时的自动退款
- 配送超时的补偿方案
5.2 分布式事务方案
推荐使用Saga模式处理跨服务操作:
- 创建订单(订单服务)
- 扣减库存(商品服务)
- 支付操作(支付服务)
- 每个步骤都需要提供补偿接口
mermaid复制sagaDiagram
participant OrderService
participant ProductService
participant PaymentService
OrderService->>ProductService: 预占库存
ProductService-->>OrderService: 成功
OrderService->>PaymentService: 发起支付
alt 支付成功
PaymentService->>OrderService: 确认订单
else 支付失败
PaymentService->>ProductService: 释放库存
end
6. 实战经验分享
6.1 缓存策略优化
外卖系统的缓存需要特殊设计:
- 菜品信息采用多级缓存(本地+Redis)
- 订单列表按用户ID分片缓存
- 商家评分使用定时任务更新缓存
- 热门商家列表使用LFU策略
重要提示:菜品价格缓存必须设置较短的过期时间(建议30秒),避免出现价格不一致问题
6.2 压力测试要点
建议在以下场景进行专项测试:
- 秒杀活动时的下单流程
- 区域性集中下单(如写字楼午间高峰)
- 骑手同时抢单场景
- 商家批量修改菜品库存
测试工具推荐:
- 使用JMeter模拟地域分布的用户
- 用Locust测试API极限承压
- 通过Chaos Engineering验证容错能力
7. 安全防护措施
外卖系统需要特别注意:
- 防止恶意刷单(设备指纹+行为分析)
- 支付风控(金额突变检测)
- 敏感信息脱敏(联系方式加密)
- API防重放攻击(nonce校验)
java复制// 订单提交防重放示例
public class OrderSubmitRequest {
@NotBlank
private String orderToken; // 前端生成的一次性令牌
@NotNull
private Long timestamp;
@NotBlank
private String signature;
public boolean isValid(AppSecret secret) {
String expect = HmacSHA256(secret.getKey(),
orderToken + timestamp);
return expect.equals(signature);
}
}
8. 持续演进方向
现代外卖系统的发展趋势:
- 智能调度算法优化配送效率
- 预测备餐减少等待时间
- 无人配送技术集成
- 跨平台订单聚合
- 低碳环保包装选项
技术栈升级建议:
- 使用Service Mesh管理微服务通信
- 采用时序数据库存储订单状态变更
- 引入图数据库处理社交化推荐
- 使用WebAssembly优化前端性能
