价值分析
以消息中心现有架构,为什么要有本次技改?
- 业务量的激增,带动了消息量的激增(渠道*模板,是n*n的关系),消息的延迟、堆积乃至丢失的风险越来越高,只靠消息中心一端已经很难做到高吞吐。
- 下游服务的消费能力不均衡,也无法预估,但弹性伸缩必须保持和消息中心同步。
本次技改的价值有以下两点:
- 明确划分消息中心的业务边界,将消息的加工处理内聚在消息中心,消费下沉到下游服务,既符合微服务架构设计理念,也利于异步解耦。
- 利用MQ的异步、蓄洪、限流等能力,有利于下游服务根据自身的消费能力弹性伸缩及动态扩展。
- 减少了一次同步请求的网络io, 提高了整个链路的性能
用户用例设计
用例图:

名词释义:
- 用户 - 消息中心上游服务。
- 通知消息 - 通知类消息(app推送,短信、邮件、语音、IM、动态消息、钉钉、微信模板消息等)。
- 系统消息 - 指业务系统业务流程流转的消息,比如注册成功异步生成用户信息的流程。
业务流程设计
消息中心在转发消息的中间过程中,对消息进行了拆分、过滤、补充和转换等操作,实现了消息的完善、分发和拦截等功能。
活动图:

改造后, 对msg-center消费的通知类消息进行拆分,有内部服务的,内部服务直接订阅消费,无内部服务的,用msg-notice进行消费。

系统交互设计
系统交互设计图:

bus负责消息路由,msg-center处理和消费通知类的消息,msg-engine处理系统类消息,notice是通知类服务,business是业务类服务。
应用架构设计
消息中心组成结构图:

关键流程时序
消息中心的核心业务是 通知类消息 和 业务类的消息 中间状态的加工、过滤等处理。
通知类消息时序图:

业务类消息时序图:

本次技改是针对通知类消息msg-center在消费消息,时序图如下:

兼容性设计
- 添加开关功能 对同步或异步操作可切换
分布式风险
- 消息的幂等性 避免消息的重复,事件码和trace_id组合判重,防止5分钟内因网络波动元素的重复。
- 消息的时效性 透传失效时间至下游,下游做好推送消息的前置校验。
- 消息的完整性 消息推送失败需要视业务情况有选择的做重试补偿机制
- 消息的全链路追踪 链路日志,消息中心需要记录消息处理和推送的日志,下游需要记录消息实际消费的状态及日志
幂等设计
消息中心怎么做?
- 规范约束上游传来的trace_id。
- 选择性考量使用MQ的失败重试机制。
- 保证同一消息不重复推送到下游MQ。
消息中心的下游服务怎么做?
- 明确第三方消息平台的接口是否做过幂等性设计。
- 选择性考量使用MQ的失败重试机制。
- 对trace_id和事件码组合过滤排重。
交互对象约定
{
"traceId": "string",
"eventNo": "string",
"mobile": "string",
"userId": 0,
"openId":"string",
"data": "string",
"startTime": "yyyy-MM-dd HH:mm:ss",
"expireTime": "yyyy-MM-dd HH:mm:ss"
}
参数名 | 类型 | 备注 | 是否必填 | 说明 |
---|---|---|---|---|
traceId | String | 链路ID | 是 | 链路标识 |
eventNo | String | 事件码 | 是 | 时间标识 |
mobile | String | 手机号 | 是 | 用户标识 |
userId | Integer | 用户ID | 否 | 用户标识 |
openId | String | 微信openId | 否 | 用户标识 |
data | String | 消息体,json字符串 | 是 | 根据不同的渠道定义(待定) |
startTime | String | 开始时间,格式:yyyy-MM-dd HH:mm:ss | 是 | 大于等于这个时间才能推 |
expireTime | String | 结束时间,格式:yyyy-MM-dd HH:mm:ss | 否 | 小于这个时间才能推,null不校验 |
发布策略
(待定)
网友评论