从零搭建多平台二手ERP中台:闲鱼、淘宝、京东、拼多多、Mercari统一调度架构

多平台二手ERP最容易走弯路的地方,是把它写成一个"超级大系统":每接一个平台,就在核心代码里加一段if-else。半年下来,发布逻辑、库存同步、订单拉取全缠在一起,接第六个平台时改一处崩三处。

正确的做法不是继续堆功能,而是把前面各篇里散落的能力组合成一个调度框架:平台差异全部锁进适配器,通用流程抽成统一管道。新增一个平台,只需要加一个适配器文件,调度、限流、合规、对账、事件全部自动复用。

这篇文章是这个系列的总装说明。它不引入新能力,只说明怎么把已有模块按依赖关系组装成一台能跑的中台。


一、中台的真正难点:不是能对接,是能调度

错误的写法是这样的:

复制代码
# 系统演示、API测试控制台:http://console.open.onebound.cn/console/?i=NewRookie

if platform == "xianyu":
    call_xianyu_publish()
elif platform == "taobao":
    call_taobao_publish()
elif platform == "mercari":
    call_mercari_publish()
# 每加一个平台,就在这里加一段

正确的方式是:业务层只调用一个统一入口,调度器负责把请求分发给对应适配器。

复制代码
业务层 → UnifiedScheduler → [灰度 → 限流 → 合规 → 适配 → 事件]
                                    ↓
                          PlatformAdapter(统一接口)
                              ├── XianyuAdapter
                              ├── TaobaoAdapter
                              ├── JingdongAdapter
                              ├── PddAdapter
                              └── MercariAdapter

关键点在于:五个平台在认证方式、拉单机制、限流配额、字段长度上的差异,全部封死在适配器内部。业务层只认UnifiedProductUnifiedOrder,完全不知道平台细节。


二、中台架构:七个模块各司其职

中台由七个模块组成,每个模块对应前面某一篇解决过的问题:

模块 职责 对应前篇
AdapterRegistry 注册、发现、路由适配器 适配器模式
UnifiedScheduler 统一 publish / sync_stock / pull_orders / ship 本篇核心
RateLimitOrchestrator 每平台独立配额管理 限流篇
ComplianceGate 发布前字段校验(标题长度、必填项) 合规篇
EventBus 发布、库存、发货事件解耦 事件驱动篇
ReconciliationHub 每日对账调度 对账篇
GrayReleaseRouter 按平台逐步放量 灰度篇

调用链路是固定的:业务请求先经过灰度过滤,再走合规门禁,然后限流,通过后交给适配器执行,成功后发事件。发布、库存同步、发货全部走这条管道,不重复实现。


三、五个平台的真实差异

这些差异必须消化在适配器内部,不能泄漏到业务层。

复制代码
class XianyuAdapter(PlatformAdapter):
    capabilities = {"publish": True, "stock": True, "order": True, "webhook": True}
    # 认证:OAuth2(淘宝开放平台)
    # 拉单:webhook 回调


class TaobaoAdapter(PlatformAdapter):
    capabilities = {"publish": True, "stock": True, "order": True, "webhook": True}
    # 认证:OAuth2 + AppKey/Secret
    # 限流:单应用约 100 次/分钟


class JingdongAdapter(PlatformAdapter):
    capabilities = {"publish": True, "stock": True, "order": True, "webhook": False}
    # 认证:AppKey + access_token + 签名
    # 拉单:轮询


class PddAdapter(PlatformAdapter):
    capabilities = {"publish": True, "stock": True, "order": True, "webhook": False}
    # 认证:ClientId/Secret + access_token
    # 限流:约 50 次/分钟,五个平台里最紧


class MercariAdapter(PlatformAdapter):
    capabilities = {"publish": True, "stock": True, "order": True, "webhook": False}
    # 认证:OAuth2(Mercari ID Platform)
    # 拉单:仅轮询

注意webhook这一列。闲鱼和淘宝有回调,京东、拼多多、Mercari只能轮询。调度器不关心这个差异,它只调adapter.list_orders(),具体是推还是拉,由适配器自己声明。


四、调度管道:所有操作共用一套逻辑

发布商品的调度逻辑如下,库存同步和发货也走同一套:

复制代码
def publish(self, product, platforms=None):
    results = []
    targets = platforms or self.registry.all_platforms()

    for platform in targets:
        # 1. 灰度过滤
        if not self.gray.should_process(platform):
            continue

        adapter = self.registry.get(platform)

        # 2. 合规门禁
        issues = self.compliance.check(platform, product)
        if issues:
            results.append(PublishResult(platform, False, "; ".join(issues)))
            continue

        # 3. 限流
        if not self.rate.acquire(platform):
            results.append(PublishResult(platform, False, "触发限流,进入队列"))
            continue

        # 4. 调用适配器
        result = adapter.publish(product)

        # 5. 成功后发事件
        if result.success:
            self.bus.publish("product.published", {
                "platform": platform,
                "product_id": result.platform_id
            })
        results.append(result)

    return results

五、几个关键运行现象

在实际跑这套框架时,有几个现象值得注意。

合规门禁会真实拦截。 测试用的商品标题有31个字符,闲鱼限制30字,Mercari限制50字。同一个商品发给两个平台,闲鱼被拦下,Mercari放行。规则按平台差异化应用,这正是门禁存在的意义。

灰度控制发布范围。 在10%灰度阶段,只有闲鱼会真正执行发布,其他平台直接跳过。未放量的平台不消耗API配额,出问题时影响面也可控。

限流配额差异巨大。 拼多多的配额大约是50次/分钟,Mercari的头部信息显示限制在60000次/分钟量级。调度器按平台独立计数,不会把宽松平台的额度套到严格平台上。

事件解耦生效。 发布成功后触发product.published事件,下游的库存、物流模块可以独立订阅,不需要发布模块主动调用它们。


六、新增一个平台只需要三步

这是整个中台设计的核心承诺。以接入Vinted为例:

python

复制代码
# 1. 写适配器,实现统一接口
class VintedAdapter(PlatformAdapter):
    @property
    def platform(self) -> str:
        return "vinted"

    def publish(self, product):
        ...

    def update_stock(self, sku, qty):
        ...

    def list_orders(self, since=None):
        ...

    def ship(self, order_id, tracking):
        ...


# 2. 注册
hub.registry.register(VintedAdapter())

# 3. 配置限流和合规规则
hub.rate.quotas["vinted"] = PlatformQuota("vinted", 1000)
hub.compliance.RULES["vinted"] = {"max_title": 100}

灰度、限流、合规、事件、对账全部自动接入。适配器模式加关注点分离,带来的复利就在这里。


七、落地时的六条规则

业务层只认统一模型。 UnifiedProductUnifiedOrder是契约,平台字段不许往上泄漏。

适配器只做翻译,不做业务判断。 不要在适配器里写"是否该发货"这类决策,它只负责把统一指令翻译成平台调用。

拉单方式由适配器声明。 capabilities["webhook"]决定调度器行为,调度器本身不做平台判断。

限流配额按平台独立配置。 永远不要把宽松平台的额度套到严格平台上。

合规规则外置为配置表。 标题长度、必填字段这些差异,放在配置里,不写进代码分支。

所有操作成功后必须发事件。 发布、库存变更、发货完成,都要触发事件,让下游解耦。


八、和前面各篇的收口关系

这篇不产生新模块,它说明的是已有模块之间的组装方式:

  • PlatformAdapter协议来自适配器模式篇

  • AdapterRegistry来自适配器模式篇的版本注册部分

  • RateLimitOrchestrator整合了限流篇和Mercari限流篇的配额表

  • ComplianceGate整合了合规篇和成色校验篇

  • EventBus来自事件驱动篇

  • GrayReleaseRouter来自灰度发布篇

  • ReconciliationHub来自对账篇

  • 统一模型来自跨境字段映射篇

  • 调度管道里的幂等处理来自幂等消费篇

整个系列要解决的不是"怎么对接27个平台",而是"怎么让第28个平台的接入成本降到最低"。

多平台中台的本质不是大系统,而是好框架。把平台差异关进适配器,把通用流程抽成管道,新增平台的成本就从"改核心代码"变成"加一个文件"。这是架构层面能带来的最直接的杠杆。

相关推荐
Francek Chen1 小时前
【大数据处理与分析】数据仓库Hive:04 数据仓库Hive概述
大数据·数据仓库·hive·hadoop·分布式
Leo.yuan1 小时前
2026国产数据仓库软件有哪些?从数据库、云数仓到数据集成平台一次讲清
大数据
红姐跨境书2 小时前
高并发场景下的本地缓存进化论:从 Go sync.Map 到 BigCache 的性能调优实践
大数据
shujudang2 小时前
业务数据分析项目中的分析方法与团队协作
大数据·数据挖掘·数据分析
径硕科技JINGdigital3 小时前
Amazon Bedrock能够为企业生成式AI应用提供哪些安全与合规支持?
大数据·人工智能
当下新鲜事3 小时前
空调机房水泵常见问题解答:赛莱默B&G冷冻泵与冷却泵技术说明
大数据·运维·物联网·业界资讯
adinnet20263 小时前
为什么 RAG 需要 Milvus?向量数据库到底存了什么
大数据·数据库
Gl�ria3 小时前
Hadoop/YARN 集群缩容:下线DN节点
大数据·hadoop·分布式
Elastic 中国社区官方博客3 小时前
使用 Elasticsearch 和 Jina 进行 AI 视频搜索:精准找到你需要的视频片段秒数
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索