
1. 项目背景与核心目标苍穹外卖day04是一个典型的外卖配送系统开发日志的阶段性记录。作为资深外卖系统开发者我参与过多个大型外卖平台的后端架构工作。这类项目通常采用敏捷开发模式以day数字的形式标记开发进度day04代表项目进入第四天或第四阶段的关键开发期。这个阶段通常需要完成以下核心任务订单状态流转机制的完整实现骑手调度算法的初步验证商家接单接口的性能优化用户端实时推送功能的联调2. 系统架构与技术选型2.1 微服务架构设计我们采用Spring Cloud Alibaba作为基础框架服务划分如下订单服务(order-service)商家服务(shop-service)配送服务(delivery-service)用户服务(user-service)支付服务(payment-service)服务注册中心使用Nacos配置中心采用Apollo消息队列选用RocketMQ。这种组合在多个外卖项目中被验证具有最佳性价比。2.2 数据库设计要点订单表的核心字段设计CREATE TABLE order ( id bigint NOT NULL AUTO_INCREMENT, order_no varchar(32) NOT NULL COMMENT 订单编号, user_id bigint NOT NULL, shop_id bigint NOT NULL, total_amount decimal(10,2) NOT NULL COMMENT 订单总金额, status tinyint NOT NULL DEFAULT 0 COMMENT 0-待支付 1-已支付 2-商家接单 3-配送中 4-已完成 5-已取消, delivery_id bigint DEFAULT NULL COMMENT 骑手ID, create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_order_no (order_no), KEY idx_user_id (user_id), KEY idx_shop_id (shop_id), KEY idx_status (status) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;3. 核心功能实现3.1 订单状态机设计采用状态模式实现订单状态流转public interface OrderState { void pay(Order order); void shopAccept(Order order); void deliveryTake(Order order); void complete(Order order); void cancel(Order order); } // 具体状态实现示例 public class WaitingPayState implements OrderState { Override public void pay(Order order) { order.setState(new PaidState()); // 支付成功逻辑... } // 其他方法抛出IllegalStateException }3.2 骑手调度算法基于贪心算法实现初始版本def dispatch_rider(orders, riders): # 订单按距离排序 sorted_orders sorted(orders, keylambda o: o.distance) # 骑手按空闲程度排序 sorted_riders sorted(riders, keylambda r: r.current_orders) assignments [] for order in sorted_orders: # 找到最近的空闲骑手 nearest_rider min( sorted_riders, keylambda r: haversine(r.location, order.pickup_location) ) assignments.append((order, nearest_rider)) nearest_rider.current_orders 1 return assignments4. 性能优化实践4.1 商家接单接口优化原始方案问题每次接单都查询完整订单信息没有批量处理能力优化方案引入Redis缓存订单基础信息实现批量接单接口添加接单频率限制优化前后对比指标优化前优化后QPS120850平均响应时间230ms45ms错误率1.2%0.3%4.2 数据库分库分表订单表按月分表策略// 分表策略实现 public class OrderShardingAlgorithm implements PreciseShardingAlgorithmLong { Override public String doSharding(CollectionString availableTargetNames, PreciseShardingValueLong shardingValue) { // 按订单ID的月份分表 LocalDateTime createTime getCreateTimeById(shardingValue.getValue()); return order_ createTime.format(DateTimeFormatter.ofPattern(yyyyMM)); } }5. 联调与测试5.1 接口自动化测试使用PostmanNewman实现// 订单创建测试用例 pm.test(创建订单成功, function() { pm.response.to.have.status(200); var jsonData pm.response.json(); pm.expect(jsonData.orderNo).to.be.a(string); }); // 商家接单测试用例 pm.test(商家接单成功, function() { pm.response.to.have.status(200); var jsonData pm.response.json(); pm.expect(jsonData.status).to.eql(2); });5.2 压力测试方案使用JMeter配置线程组500并发持续时间10分钟断言响应时间500ms错误率0.5%关键监控指标服务CPU/Memory数据库QPSRedis命中率MQ堆积量6. 踩坑实录6.1 分布式事务问题场景支付成功后更新订单状态失败 解决方案引入Seata AT模式GlobalTransactional public void payOrder(Long orderId) { // 1. 支付操作 paymentService.pay(orderId); // 2. 更新订单状态 orderService.updateStatus(orderId, OrderStatus.PAID); }6.2 缓存一致性问题问题现象商家看到订单状态延迟 解决方案采用Cache Aside Pattern设置合理的过期时间(30s)关键操作主动清除缓存public void acceptOrder(Long orderId) { // 1. 更新数据库 orderDao.updateStatus(orderId, OrderStatus.ACCEPTED); // 2. 删除缓存 redisTemplate.delete(order: orderId); }7. 项目演进建议引入地理围栏技术优化配送范围判断增加订单预估送达时间算法实现动态定价策略构建用户画像系统提升推荐准确率技术栈升级路线当前Spring Boot 2.7 MySQL 8.0中期引入Flink实时计算长期向云原生架构迁移