在云通信平台演进的过程中,“多产品”几乎是一个必然阶段:短信、语音、邮件、WhatsApp、RCS 等能力不断叠加。如果没有清晰的解耦设计,系统很快就会从“可扩展”滑向“不可维护”。本文从工程实践出发,聊一套多产品通信平台的解耦设计思路。
一、为什么必须解耦?
很多团队在早期会采用“功能叠加式”架构:短信一套逻辑、语音一套逻辑,调度、计费、通道管理各自实现一遍。短期看交付很快,但随着产品增多,问题会迅速暴露:
- 重复建设严重:每个产品都有一套发送、重试、回执逻辑
- 资源无法复用:通道能力割裂,无法统一调度
- 系统耦合度高:一个模块变更牵一发动全身
- 扩展成本指数级上升
本质上,这是“按产品建系统”,而不是“按能力建系统”。
二、核心思路:能力抽象 + 分层解耦
多产品通信平台的解耦,本质是把“产品差异”收敛到边界,把“共性能力”沉淀为中台。
整体可以拆为三层:
1. 接入层(Access Layer)
面向客户的统一入口
职责:
- 提供统一 API(HTTP / SMPP / Webhook)
- 做协议适配与参数标准化
- 鉴权、限流、签名校验
关键点:
接入层不关心“短信还是语音”,只处理“通信请求”
2. 能力中台层(Core Capability Layer)
这是解耦的核心。
将所有通信产品抽象为几个通用能力:
(1)消息模型统一
定义统一 Message 结构,例如:
- destination(目标)
- content(内容)
- channel_type(sms / voice / email / ott)
- priority(优先级)
- metadata(扩展字段)
这样短信和语音只是不同“类型”的消息。
(2)调度引擎(Dispatcher)
统一调度逻辑,而不是每个产品一套:
- 路由策略(国家 / 运营商 / 成本 / 成功率)
- 多通道择优(动态权重)
- 灰度与AB测试
- 实时切换(failover)
(3)通道抽象层(Channel Layer)
对接下游供应商的统一封装:
Send(message) -> Result
Query(status) -> Report
屏蔽差异:
- 不同协议(HTTP / SMPP / SIP)
- 不同返回码
- 不同回执机制
(4)回执与状态系统
统一处理:
- DLR(短信回执)
- 语音通话状态(接通 / 挂断)
- 邮件投递状态
避免每个产品一套回执系统。
(5)计费与配额系统
抽象计费维度:
- 按条(短信)
- 按时长(语音)
- 按成功(邮件)
统一账单、统一余额、统一风控。
3. 产品层(Product Layer)
这一层才是“差异化”的地方:
- 短信验证码(OTP)
- 营销短信
- 语音通知 / 语音验证码
- 邮件触达
- OTT 消息(如 WhatsApp)
产品层只做两件事:
- 组装业务逻辑(模板、签名、策略)
- 调用中台能力
产品不再直接操作通道,而是调用“调度能力”
三、关键解耦设计点
1. 用“事件驱动”替代强依赖
发送、回执、计费全部事件化:
- MessageCreated
- MessageSent
- MessageDelivered
- MessageFailed
通过消息队列解耦(Kafka / Pulsar):
- 发送与计费解耦
- 回执与业务解耦
- 实现异步扩展
2. 通道能力插件化
新增一个供应商,不应该改核心代码。
建议设计为:
- Channel Driver(驱动层)
- Channel Adapter(适配层)
支持动态加载:
sms-twilio
sms-infobip
voice-twilio
email-sendgrid
3. 路由策略配置化
不要写死在代码里:
- 国家维度
- 成本优先 / 成功率优先
- 时段策略
- 业务优先级
全部通过配置中心动态调整。
4. 多产品统一限流与风控
统一控制:
- QPS 限制
- 单用户发送频率
- 黑名单 / 灰名单
- 内容合规检测
避免每个产品各自为战。
四、一套可落地的架构示意(文字版)
[ Client / API ]
│
┌──── 接入层 ────┐
│ API Gateway │
└──────┬────────┘
│
┌──────────▼──────────┐
│ 消息统一模型层 │
└──────────┬──────────┘
│
┌──────────▼──────────┐
│ 调度引擎 Dispatcher │
└──────────┬──────────┘
│
┌─────────────▼─────────────┐
│ 通道抽象层 Channel Hub │
└──────┬──────────┬────────┘
│ │
[SMS Channel] [Voice Channel] ...
│
下游供应商(多线路)
异步侧:
Message Queue → 回执系统 → 计费系统 → 数据分析
五、实践中的几个坑
1. “伪解耦”
表面分层,但:
- 调度写死产品逻辑
- 通道直接感知业务字段
结果还是耦合。
2. 过度抽象
一开始就设计“完美模型”,反而拖慢交付。
建议:
先抽象“发送模型 + 通道接口”,逐步演进
3. 回执系统被忽视
很多系统“发得出去”,但:
- 状态不准
- 无法追踪链路
- 客户投诉无定位
回执系统必须与发送同等重要。
4. 数据一致性问题
- 发送成功但未计费
- 回执延迟导致状态错乱
需要:
- 最终一致性设计
- 幂等机制
- 补偿任务
六、总结
多产品通信平台的解耦,本质不是“拆服务”,而是三件事:
- 统一模型(Message 抽象)
- 能力中台化(调度 / 通道 / 回执 / 计费)
- 产品轻量化(只做业务编排)
做到这三点,系统会具备三个关键能力:
- 新产品接入成本极低
- 通道资源可复用
- 整体系统可持续演进
在云通信这个高度依赖“稳定性 + 可扩展性”的行业里,解耦设计不是锦上添花,而是生死线。