首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >开源外卖系统多运力并存模型设计:自营+众包架构实现

开源外卖系统多运力并存模型设计:自营+众包架构实现

原创
作者头像
万岳教育Lili
发布2026-03-14 16:44:52
发布2026-03-14 16:44:52
980
举报

很多人做开源外卖系统时,一开始只考虑“自营骑手”。 但只要订单量一上来,就会发现一个现实问题:

  • 高峰期运力不够
  • 低峰期人力成本过高
  • 跨区域订单履约困难

这时候,单一运力模式必然成为瓶颈

开源外卖系统
开源外卖系统

真正成熟的开源外卖系统,必须支持:

自营骑手 + 众包骑手 + 第三方运力并存

今天我们从架构设计 + 数据结构 + 核心代码实现三个层面,拆解多运力模型如何落地。


一、多运力模型的核心设计思路

多运力并存,本质是三件事:

  1. 订单如何选择运力类型
  2. 不同运力如何分账
  3. 调度如何统一抽象

我们先定义一个核心原则:

订单只认“运力策略”,不直接绑定某个骑手类型。


二、数据库结构设计

1. 运力类型表

代码语言:javascript
复制
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
);

说明:

  • SELF:自营骑手
  • CROWD:众包骑手
  • THIRD_PARTY:第三方运力接口

2. 骑手表(统一抽象)

代码语言:javascript
复制
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 区分来源。


3. 订单表增加运力字段

代码语言:javascript
复制
ALTER TABLE orders 
ADD COLUMN provider_id BIGINT,
ADD COLUMN dispatch_status VARCHAR(20);

三、运力选择策略设计

多运力的核心在于“派单策略”。

常见策略:

  1. 优先自营(成本可控)
  2. 自营无可用骑手 → 自动切换众包
  3. 众包仍不足 → 调用第三方接口
开源外卖系统
开源外卖系统

四、核心调度逻辑实现(Java示例)

1. 运力策略接口

代码语言:javascript
复制
public interface DispatchStrategy {
    Rider dispatch(Order order);
}

2. 自营策略实现

代码语言:javascript
复制
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()
        );
    }
}

3. 众包策略实现

代码语言:javascript
复制
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()
        );
    }
}

4. 运力调度中心(核心控制)

代码语言:javascript
复制
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);
    }
}

核心思想:

策略模式 + 运力优先级控制


五、分账逻辑差异处理

不同运力,成本不同。

示例:

代码语言:javascript
复制
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 分布式锁:

代码语言:javascript
复制
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 删除。

评论
作者已关闭评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、多运力模型的核心设计思路
  • 二、数据库结构设计
    • 1. 运力类型表
    • 2. 骑手表(统一抽象)
    • 3. 订单表增加运力字段
  • 三、运力选择策略设计
  • 四、核心调度逻辑实现(Java示例)
    • 1. 运力策略接口
    • 2. 自营策略实现
    • 3. 众包策略实现
    • 4. 运力调度中心(核心控制)
  • 五、分账逻辑差异处理
  • 六、高并发优化建议
  • 七、为什么多运力模型很重要?
  • 结语
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档