
很多人做开源外卖系统时,一开始只考虑“自营骑手”。 但只要订单量一上来,就会发现一个现实问题:
这时候,单一运力模式必然成为瓶颈。

真正成熟的开源外卖系统,必须支持:
自营骑手 + 众包骑手 + 第三方运力并存
今天我们从架构设计 + 数据结构 + 核心代码实现三个层面,拆解多运力模型如何落地。
多运力并存,本质是三件事:
我们先定义一个核心原则:
订单只认“运力策略”,不直接绑定某个骑手类型。
CREATE TABLE delivery_provider (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
provider_name VARCHAR(50),
provider_type VARCHAR(20), -- SELF / CROWD / THIRD_PARTY
status TINYINT DEFAULT 1,
create_time DATETIME
);说明:
CREATE TABLE rider (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50),
phone VARCHAR(20),
provider_id BIGINT,
status VARCHAR(20), -- ONLINE / OFFLINE / BUSY
latitude DECIMAL(10,6),
longitude DECIMAL(10,6),
FOREIGN KEY (provider_id) REFERENCES delivery_provider(id)
);关键点:
不管自营还是众包,统一用 rider 表管理,只通过 provider_id 区分来源。
ALTER TABLE orders
ADD COLUMN provider_id BIGINT,
ADD COLUMN dispatch_status VARCHAR(20);多运力的核心在于“派单策略”。
常见策略:

public interface DispatchStrategy {
Rider dispatch(Order order);
}public class SelfDispatchStrategy implements DispatchStrategy {
@Override
public Rider dispatch(Order order) {
List<Rider> riders = riderRepository.findAvailableRiders("SELF");
return riders.stream()
.min(Comparator.comparing(r -> distance(r, order)))
.orElse(null);
}
private double distance(Rider rider, Order order) {
return GeoUtil.calculateDistance(
rider.getLatitude(),
rider.getLongitude(),
order.getLatitude(),
order.getLongitude()
);
}
}public class CrowdDispatchStrategy implements DispatchStrategy {
@Override
public Rider dispatch(Order order) {
List<Rider> riders = riderRepository.findAvailableRiders("CROWD");
return riders.stream()
.min(Comparator.comparing(r -> distance(r, order)))
.orElse(null);
}
private double distance(Rider rider, Order order) {
return GeoUtil.calculateDistance(
rider.getLatitude(),
rider.getLongitude(),
order.getLatitude(),
order.getLongitude()
);
}
}public class DispatchCenter {
private DispatchStrategy selfStrategy;
private DispatchStrategy crowdStrategy;
public Rider dispatch(Order order) {
Rider rider = selfStrategy.dispatch(order);
if (rider != null) {
order.setProviderId(1L); // SELF
return rider;
}
rider = crowdStrategy.dispatch(order);
if (rider != null) {
order.setProviderId(2L); // CROWD
return rider;
}
// 调用第三方接口
return thirdPartyDispatch(order);
}
private Rider thirdPartyDispatch(Order order) {
// 调用第三方API
ThirdPartyResponse response = thirdPartyApi.createOrder(order);
return convert(response);
}
}核心思想:
策略模式 + 运力优先级控制
不同运力,成本不同。
示例:
public BigDecimal calculateRiderIncome(Order order) {
if (order.getProviderType().equals("SELF")) {
return order.getDeliveryFee().multiply(new BigDecimal("0.8"));
}
if (order.getProviderType().equals("CROWD")) {
return order.getDeliveryFee().multiply(new BigDecimal("0.9"));
}
if (order.getProviderType().equals("THIRD_PARTY")) {
return order.getDeliveryFee().subtract(order.getThirdPartyCost());
}
return BigDecimal.ZERO;
}重点:
多运力场景下,必须避免:
可以使用 Redis 分布式锁:
String lockKey = "dispatch_lock:" + order.getId();
Boolean success = redisTemplate.opsForValue()
.setIfAbsent(lockKey, "1", 10, TimeUnit.SECONDS);
if (!success) {
throw new RuntimeException("正在派单中");
}如果只有自营骑手:
如果只有众包:
多运力并存的意义是:
平峰自营,高峰众包,极端情况第三方托底。
这才是可扩展架构。

开源外卖系统如果只停留在“下单+接单”,那只是基础版本。
真正成熟的平台,必须具备:
做系统,不是堆功能,而是设计结构。
多运力并存模型,是外卖系统从“小工具”走向“平台级架构”的关键一步。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。