1. 项目背景与核心价值
外卖平台开发是当前互联网行业中典型的全栈实战项目,涉及前后端分离架构、高并发订单处理、实时地理位置服务等核心技术难点。"苍穹外卖"作为教学演示项目,完整覆盖了从用户下单到商家接单、骑手配送的全业务流程,是开发者掌握企业级应用开发的优质练手素材。
这个项目特别适合两类人群:
- 刚学完SpringBoot+Vue技术栈需要综合实践的开发者
- 准备面试需要项目经验补充的求职者
我在复盘这个项目时,重点梳理了三个维度的技术要点:
- 复杂权限系统的RBAC实现方案
- 高并发场景下的订单状态机设计
- 地理位置服务在配送环节的应用
2. 技术架构解析
2.1 整体技术栈选型
采用现在主流的"前后端分离+微服务"架构:
- 前端:Vue3 + Element Plus + Axios
- 网关:Spring Cloud Gateway
- 业务服务:
- 用户服务:SpringBoot + JWT
- 订单服务:SpringBoot + Redis + RabbitMQ
- 配送服务:SpringBoot + MongoDB(地理位置查询)
- 数据层:MySQL 8.0 + MyBatis-Plus
特别提醒:MySQL一定要用8.0+版本,因为项目中使用到了窗口函数等新特性
2.2 权限系统设计要点
采用改良版的RBAC模型实现多角色权限控制:
// 权限拦截器核心逻辑示例 public boolean preHandle(...) { String token = request.getHeader("Authorization"); Claims claims = JwtUtil.parseToken(token); String role = claims.get("role"); String uri = request.getRequestURI(); if(!permissionService.checkAccess(role, uri)) { throw new UnauthorizedException(); } return true; }实际开发中容易踩的坑:
- 权限路径配置要使用ant风格(如
/admin/**) - 前端按钮级权限要用
v-permission指令 - JWT过期时间建议设为8小时(兼顾安全与体验)
3. 核心业务实现
3.1 订单状态机设计
采用状态模式实现订单生命周期管理:
stateDiagram [*] --> 待支付 待支付 --> 已取消: 超时未支付 待支付 --> 已支付: 支付成功 已支付 --> 配送中: 商家接单 配送中 --> 已完成: 用户确认 配送中 --> 已取消: 用户退款关键实现代码:
public class OrderStateMachine { private OrderState currentState; public void pay() { if(currentState instanceof UnpaidState) { currentState = new PaidState(); // 触发支付成功事件 eventPublisher.publish(new OrderPaidEvent(this)); } } // 其他状态转换方法... }3.2 地理位置服务集成
使用MongoDB的2dsphere索引实现附近商家查询:
@Repository public interface ShopRepository extends MongoRepository<Shop, String> { @Query("{'location': {$near: {$geometry: {type: 'Point', coordinates: ?0}, $maxDistance: ?1}}}") List<Shop> findNearbyShops(double[] coordinates, double maxDistance); }性能优化技巧:
- 建立复合索引:
db.shops.createIndex({ location: "2dsphere", status: 1 }) - 使用GeoHash预处理坐标数据
- 客户端做结果缓存(Redis GEO)
4. 典型问题解决方案
4.1 订单超时处理
采用RabbitMQ的延迟队列实现:
// 配置延迟交换机 @Bean public CustomExchange orderDelayExchange() { Map<String, Object> args = new HashMap<>(); args.put("x-delayed-type", "direct"); return new CustomExchange("order.delay", "x-delayed-message", true, false, args); } // 发送延迟消息 rabbitTemplate.convertAndSend("order.delay", "order.cancel", orderId, msg -> { msg.getMessageProperties().setDelay(30 * 60 * 1000); // 30分钟 return msg; });4.2 高并发减库存
使用Redis+Lua脚本保证原子性:
-- stock.lua local key = KEYS[1] local change = tonumber(ARGV[1]) local stock = tonumber(redis.call('GET', key)) if stock >= change then return redis.call('INCRBY', key, -change) else return -1 endJava调用示例:
Long result = redisTemplate.execute( stockScript, Collections.singletonList("stock:"+skuId), String.valueOf(quantity) );5. 项目复盘建议
根据我的实施经验,建议重点完善以下监控指标:
- 订单各状态转换耗时(Prometheus + Grafana)
- 地理位置查询响应时间(ELK日志分析)
- 支付成功率看板(自定义埋点)
调试时的小技巧:
- 使用Postman的Environment功能管理多环境配置
- 用Charles抓包分析微信支付回调
- 在Vue.config.js中配置proxy解决跨域
这个项目最值得深入挖掘的三个扩展方向:
- 接入智能派单算法优化配送路径
- 实现基于用户画像的推荐系统
- 增加实时聊天客服功能(WebSocket)