从0到1搭建外卖跑腿配送系统的全流程解析
同城即时履约系统本质上是一个多角色实时调度与地理位置驱动的协同平台,其核心围绕用户端、商家端、骑手端和管理后台四大组成部分。
接下来将从业务流程到技术架构,再到核心代码实现,全面解析一套可落地的系统设计方案。
外卖跑腿配送系统
一、系统整体架构设计
一个标准的外卖跑腿系统通常采用分层微服务或模块化架构设计。
1. 业务端结构
- 用户端:负责下单、支付与追踪订单
- 商家端:处理接单、出餐及订单管理
- 骑手端:进行抢单或派单、配送与签收
- 管理后台:实现订单调度、风控与数据分析
2. 技术架构
- 前端:Vue、React、小程序或App
- 后端:Java Spring Boot、Node.js或Go
- 数据库:MySQL搭配Redis
- 地图服务:高德或Google Maps
- 消息系统:WebSocket或MQTT
- 定位系统:GPS与LBS
二、核心业务流程
外卖跑腿系统的主要链路如下:
- 用户下单
- 商家接单
- 系统派单或抢单
- 骑手接单
- 骑手取餐
- 骑手配送
- 完成订单结算与评价
关键点在于第3步的派单逻辑。
三、核心模块拆解
1. 订单模块
订单是整个系统的核心数据结构。
示例:订单表设计(简化)
CREATE TABLE orders (id BIGINT PRIMARY KEY AUTO_INCREMENT,user_id BIGINT,merchant_id BIGINT,rider_id BIGINT,status VARCHAR(20),total_amount DECIMAL(10,2),create_time DATETIME,update_time DATETIME);2. 下单接口(后端示例)
Node.js 示例
app.post("/order/create", async (req, res) => {const { userId, merchantId, items } = req.body;// 1. 计算金额const total = items.reduce((sum, item) => {return sum item.price * item.count;}, 0);// 2. 创建订单const order = await db.orders.create({user_id: userId,merchant_id: merchantId,total_amount: total,status: "PENDING"});// 3. 写入Redis用于派单await redis.lpush("order_queue", order.id);res.json({success: true,orderId: order.id});});3. 派单核心逻辑(重点)
外卖系统的智能化核心在于如何匹配最近的骑手。
思路:
- 获取订单位置
- 查找附近骑手(LBS)
- 计算距离
- 分配最近骑手
Redis GEO实现骑手定位
// 骑手上线(存位置)await redis.geoadd("riders_location",longitude,latitude,riderId);查询附近骑手
const riders = await redis.georadius("riders_location",orderLng,orderLat,3,// 3公里范围"km","WITHDIST","COUNT",5);派单逻辑(核心代码)
async function dispatchOrder(orderId, orderLng, orderLat) {const riders = await redis.georadius("riders_location",orderLng,orderLat,5,"km","WITHDIST");if (!riders.length) {throw new Error("暂无可用骑手");}// 按距离排序riders.sort((a, b) => a[1] - b[1]);const selectedRider = riders[0][0];// 更新订单await db.orders.update({where: { id: orderId },data: {rider_id: selectedRider,status: "DISPATCHED"}});// 通知骑手(WebSocket/MQTT)notifyRider(selectedRider, orderId);return selectedRider;}4. 实时订单推送(WebSocket)
骑手必须做到秒级接收订单信息。
const WebSocket = require("ws");const wss = new WebSocket.Server({ port: 8080 });wss.on("connection", (ws) => {ws.on("message", (msg) => {const data = JSON.parse(msg);if (data.type === "rider_login") {ws.riderId = data.riderId;}});});// 推送订单function notifyRider(riderId, orderId) {wss.clients.forEach(client => {if (client.riderId === riderId) {client.send(JSON.stringify({type: "NEW_ORDER",orderId}));}});}5. 骑手接单逻辑
app.post("/rider/accept", async (req, res) => {const { riderId, orderId } = req.body;const order = await db.orders.findById(orderId);if (order.status !== "DISPATCHED") {return res.json({ success: false, msg: "订单已被接单" });}await db.orders.update({where: { id: orderId },data: {status: "ACCEPTED",rider_id: riderId}});res.json({ success: true });});6. 定位更新(骑手端)
骑手位置需要持续上报,以确保派单精准。
setInterval(() => {navigator.geolocation.getCurrentPosition(async (pos) => {await fetch("/rider/location/update", {method: "POST",body: JSON.stringify({riderId,lng: pos.coords.longitude,lat: pos.coords.latitude})});});}, 5000);后端存储更新:
app.post("/rider/location/update", async (req, res) => {const { riderId, lng, lat } = req.body;await redis.geoadd("riders_location", lng, lat, riderId);res.json({ success: true });});四、关键技术难点
1. 高并发订单处理
- Redis队列削峰
- MQ异步派单
- 分库分表
2. 实时性
- WebSocket替代HTTP轮询
- MQTT优化移动端连接
3. 距离计算
- Redis GEO(推荐)
- Haversine公式(备用)
4. 防止抢单冲突
- 分布式锁(Redis SETNX)
const lock = await redis.set("order_lock_" orderId, riderId, "NX", "EX", 10);if (!lock) {return "订单已被抢";}五、系统升级方向(进阶)
若要构建商业级系统,必须补充以下进阶功能:
- 智能派单:基于距离、负载和评分的AI算法
- 动态调度:实现订单合并配送
- 路径规划优化:采用A*或Dijkstra算法
- 风控系统:检测异常骑手行为
- 大数据分析:进行热区预测
外卖跑腿配送系统
六、总结
外卖跑腿配送系统的核心不在于下单本身,而在于派单算法、实时通信与高并发处理这三项技术难点。只有将这三个环节做好,系统才能真正实现稳定可靠的商业级运作。