外卖平台的实时派单,本质是一个 高频写入 + 快速查询 + 高并发 的技术难题。传统数据库方案往往在查询效率和并发控制上遇到瓶颈,而 SpringBoot + GeoHash + Redis 的组合恰好能在三方面实现突破。
随着即时配送行业的加速发展,外卖平台的订单与骑手规模呈现指数级增长。某头部平台每天处理超百万订单,在线骑手数量超过 20 万。这样庞大的规模带来了三大核心挑战:
- 位置更新高频:骑手每 3 秒上报一次坐标,单日产生 5.76 亿条位置数据,传统数据库难以承载高频写入。
- 派单需快速就近匹配:系统需在 200ms 内返回 3 公里范围内候选骑手,而传统 SQL 基于
ST_Distance的全表计算常常超过 500ms。 - 高并发下避免数据竞争:高峰期同时触发 1000+ 订单派单,若处理不当会出现锁冲突与数据不一致,直接影响用户体验。
传统方案在 查询效率、数据可靠性、并发处理与边界匹配 上存在明显短板。为破解瓶颈,本文将介绍如何借助 SpringBoot + GeoHash + Redis,搭建一个高效、可靠且可扩展的实时派单系统。
为何选择 GeoHash?
空间降维:二维转一维
GeoHash 使用 Base32 编码将经纬度转为字符串(如 39.908823,116.397470 → wx4g89)。这样,本来需要在二维平面计算的“附近骑手”问题,可以简化为字符串前缀匹配,查询性能提升一个数量级。
精度灵活
GeoHash 的长度决定了定位精度:
- 6 位(如
wx4g89):约 1 公里范围,适合全城范围的粗粒度筛选。 - 7 位(如
wx4g89e):约 100 米范围,适合最后一公里的精匹配。
这种灵活性避免了过度精确带来的数据分散,同时兼顾效率与准确性。
Redis 提供原生地理支持
Redis 内置了 GEOADD、GEORADIUS 等命令,可以直接存储骑手坐标与执行范围查询。结合 Hash 结构存储 GeoHash → 骑手ID 的映射,可以轻松支撑 每秒十万次位置更新与查询。
解决边界问题
仅查询单个 GeoHash 区域会漏掉边界骑手。通过 目标 GeoHash + 相邻 8 个 GeoHash 的策略,可以覆盖订单周边区域,确保不会遗漏临近骑手。
系统设计
整体架构
系统分为四层:
- 感知层:骑手端 APP 每 3 秒上传位置;用户端下单上传收货地址。
- 接入层:SpringBoot 接收请求,校验参数。
- 业务层:GeoHash 转码、派单计算逻辑。
- 存储层:Redis 保存骑手位置、GeoHash 映射、订单状态。
数据流程
骑手位置上报
- APP →
POST /rider/report - 转换为 GeoHash,更新 Redis(GEO + Hash)。
订单派单
- 用户下单 →
POST /order/dispatch - 流程:
收货地址 → GeoHash
获取目标 + 相邻 8 个 GeoHash 下的骑手
计算距离,筛选 在线 + 未超载 + 3 公里内 骑手
排序取 Top3,推送派单通知
数据模型
骑手位置模型
package com.icoderoad.dispatch.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 骑手位置模型
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class RiderLocation {
private String riderId; // 骑手ID
private double lng; // 经度
private double lat; // 纬度
private String geoHash; // GeoHash
private boolean online; // 是否在线
private i
SpringBoot+GeoHash实现高效派单

最低0.47元/天 解锁文章
188

被折叠的 条评论
为什么被折叠?



