多平台二手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
关键点在于:五个平台在认证方式、拉单机制、限流配额、字段长度上的差异,全部封死在适配器内部。业务层只认UnifiedProduct和UnifiedOrder,完全不知道平台细节。
二、中台架构:七个模块各司其职
中台由七个模块组成,每个模块对应前面某一篇解决过的问题:
| 模块 | 职责 | 对应前篇 |
|---|---|---|
| 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}
灰度、限流、合规、事件、对账全部自动接入。适配器模式加关注点分离,带来的复利就在这里。
七、落地时的六条规则
业务层只认统一模型。 UnifiedProduct和UnifiedOrder是契约,平台字段不许往上泄漏。
适配器只做翻译,不做业务判断。 不要在适配器里写"是否该发货"这类决策,它只负责把统一指令翻译成平台调用。
拉单方式由适配器声明。 capabilities["webhook"]决定调度器行为,调度器本身不做平台判断。
限流配额按平台独立配置。 永远不要把宽松平台的额度套到严格平台上。
合规规则外置为配置表。 标题长度、必填字段这些差异,放在配置里,不写进代码分支。
所有操作成功后必须发事件。 发布、库存变更、发货完成,都要触发事件,让下游解耦。
八、和前面各篇的收口关系
这篇不产生新模块,它说明的是已有模块之间的组装方式:
-
PlatformAdapter协议来自适配器模式篇 -
AdapterRegistry来自适配器模式篇的版本注册部分 -
RateLimitOrchestrator整合了限流篇和Mercari限流篇的配额表 -
ComplianceGate整合了合规篇和成色校验篇 -
EventBus来自事件驱动篇 -
GrayReleaseRouter来自灰度发布篇 -
ReconciliationHub来自对账篇 -
统一模型来自跨境字段映射篇
-
调度管道里的幂等处理来自幂等消费篇
整个系列要解决的不是"怎么对接27个平台",而是"怎么让第28个平台的接入成本降到最低"。
多平台中台的本质不是大系统,而是好框架。把平台差异关进适配器,把通用流程抽成管道,新增平台的成本就从"改核心代码"变成"加一个文件"。这是架构层面能带来的最直接的杠杆。