华为云 SMN 简单消息通知实践:事件驱动的异步解耦落地
在微服务与多产品集成的架构里,"谁在什么时候做了什么"这件事,往往不该由调用方同步追问,而应该由一个可靠的事件总线来广播。华为云 SMN(Simple Message Notification,简单消息通知)就是扮演这个角色:提供 Topic 订阅发布与 Queue 队列两种模型,把"事件发生"和"事件处理"彻底解耦。本文结合一次真实的告警聚合改造,聊聊 SMN 的接入方式、典型用法和几个踩过的坑。
一、Topic 与 Queue,先想清楚用哪个
SMN 有两种基础模型,选型上容易混淆:
1. Topic 订阅发布:发布方只管往 Topic 发,多个订阅方各自独立消费。适合"一个事件、多方关心"的场景,比如发布上线事件同时通知运维群、更新公告页、写审计日志。订阅方可以是 HTTP 端点、函数、Kafka、RDS 事件等,端点之间完全隔离,一个订阅方挂了不影响其他订阅方。
2. Queue 队列:生产方发队列、消费方拉取或回调,每条消息有明确的消费生命周期。适合任务削峰、异步重试、延迟任务这类"一个任务、逐个处理"的场景。
一句话区分:关心"通知谁"用 Topic,关心"任务排队"用 Queue。
二、典型场景:把散落的服务告警收拢到一个入口
我们之前遇到的问题是:ECS 主机监控、RDS 慢 SQL、OBS 桶容量告警分散在不同产品的告警通道,运维要么收邮件要么盯控制台,响应不及时。改造思路是统一走 SMN:
1. 各云产品侧配置告警通知,目标指向一个聚合服务(HTTP 端点);
2. 聚合服务收到事件后,按级别和来源分类,转发到不同的 Topic:critical 事件走电话/短信通道,warning 事件走 IM 机器人;
3. 所有事件同时落一份到 Queue,供后台做趋势分析和周报。
改造后好处很明显:告警源和通知渠道互相解耦,新增一个通知渠道只需要加一个订阅,改一个告警源也不影响下游;聚合服务挂了可以配置重试策略,消息不会丢。
三、几个实操要点和踩坑记录
1. 签名与鉴权:用 SDK 时注意 AK/SK 最小权限,SMN 的 Topic 和 Queue 权限是分开的,只读订阅和发布权限不要一把梭给同一个 IAM 用户。
2. HTTP 订阅的响应要求:SMN 推送 HTTP 通知时,订阅端点必须在规定时间内返回 2xx 才会认为投递成功,否则按重试策略重发(默认最多重试约 24 小时)。我们最初的端点是异步落库,响应太慢导致大量重发,把处理逻辑改成"先快速入库 ack,再异步处理"后重发率降到零。
3. 消息幂等:既然重发是特性,消费端就必须幂等。SMN 消息自带 MessageId,入库前去重是最简单的做法。
4. 过滤表达式:Topic 订阅支持按属性过滤,把过滤规则写在订阅侧而不是消费侧,能显著减少无效流量。
5. Queue 的可见性超时:消费端处理耗时要小于队列的可见性超时,否则消息会被"再投一次"造成重复消费。长任务要么调大超时,要么处理完主动删除消息。
四、和其他产品怎么配合
SMN 和 FunctionGraph 是天然组合:Topic 直接订阅函数,事件来了就触发一段逻辑,无需维护常驻服务,冷启动对告警聚合这类场景完全够用。和 OBS 搭配时,桶事件(对象创建/删除)可以订阅到 Topic,做对象入库索引、图片转码触发等。和 RDS 搭配,实例异常事件也能走 SMN 统一出口。
五、小结
SMN 的价值不在功能多,而在"解耦"这两个字:发布方不需要知道有几个下游、下游在不在、处理多慢。只要事件可靠地进了 Topic 或 Queue,剩下的交给订阅方各自处理。做事件驱动架构时,建议从最简单的告警收拢场景起步,把 Topic/Queue 选型、HTTP 订阅重试、消费幂等这三件事做扎实,再往复杂的编排上走。
- 点赞
- 收藏
- 关注作者
评论(0)