Amazon SNS 通知设计 - 扇出模式与消息过滤的最佳实践

SNS 的发布/订阅模型、消息过滤策略、FIFO 主题的严格排序、跨账户订阅的设计模式。与 SQS 组合的扇出架构也一并解析。

主题设计与订阅

SNS 主题分为 Standard 和 FIFO 两种。Standard 主题提供几乎无限的吞吐量,消息顺序为尽力而为。FIFO 主题按消息组 ID 提供严格的顺序保证,并通过消息重复数据删除 ID 进行去重。FIFO 主题的订阅者仅限于 SQS FIFO 队列。订阅协议支持 SQS、Lambda、HTTP/HTTPS、邮件、SMS 和 Kinesis Data Firehose。通过附加消息属性,可实现基于订阅过滤策略的条件路由。

扇出模式设计

SNS + SQS 扇出模式将多个 SQS 队列订阅到一个 SNS 主题,一次发布即可将消息分发到所有队列。每个队列的消费者独立处理,一个消费者的故障不影响其他消费者。此模式常用于订单处理系统——一个订单事件同时分发到库存更新队列、邮件通知队列和分析记录队列。扇出目标数量几乎没有实际上限(每账户订阅配额为 12,500,000),添加新处理时只需添加订阅,无需修改发布者。跨账户扇出通过主题策略允许其他账户的 SQS 队列 Subscribe,保持微服务间的松耦合。

订阅过滤与配信保证

订阅过滤策略分为属性过滤和负载过滤两种。属性过滤基于消息属性(字符串精确匹配、前缀匹配、数值比较、exists 判定)定义条件。负载过滤对消息正文的 JSON 路径执行过滤,支持嵌套字段。过滤在 SNS 侧执行,不符合条件的消息不会分发给订阅者,减少下游处理成本和噪音。配信失败的重试策略因协议而异,HTTP/HTTPS 端点使用指数退避(最长 23 天)重试。重试后仍无法配信的消息被发送到死信队列 (DLQ),可后续调查或重新处理。DLQ 的重新驱动功能允许在问题解决后将消息重新配信到原始订阅。

FIFO 主题与消息属性

FIFO 主题提供消息顺序保证和去重,与 FIFO SQS 队列组合实现严格的顺序处理。消息组 ID 将消息逻辑分组,保证组内顺序。消息属性附加元数据(事件类型、优先级、来源),订阅过滤策略实现基于属性的路由。消息数据保护自动检测 PII(个人身份信息),可配置遮蔽或拒绝策略。 要深入了解通知设计的集成模式,可参考相关专业书籍 (Amazon)

设计陷阱与运维注意事项

SNS 的最大消息大小为 256 KB,超过此限制的负载需存储到 S3 并仅通过 SNS 发送指针(Extended Client Library 模式)。FIFO 主题的吞吐量上限为每消息组每秒 300 条消息(批处理时 3,000 条),高吞吐场景需分散消息组 ID。过滤策略复杂度增加会使调试困难,建议每个订阅的过滤条件控制在 5 个属性以内,复杂路由考虑使用 EventBridge。HTTP/HTTPS 端点订阅在确认完成前不会收到消息,端点实现必须包含确认令牌处理。启用消息加密 (SSE) 后,订阅者的 IAM 角色需要 KMS 解密权限,这一点常被忽略。

SNS 与 EventBridge 的选择

SNS 和 EventBridge 都是事件驱动架构的核心,但特性不同。SNS 擅长简单扇出和协议多样性(SQS、Lambda、HTTP、SMS、邮件),消息配信延迟低。EventBridge 擅长对事件结构的复杂规则匹配(100+ 字段模式)、通过 Schema Registry 实现类型安全、以及 SaaS 集成。实务中的选择:应用内部扇出(订单 → 多个队列)用 SNS,服务间事件路由(复杂条件分支、外部 SaaS 事件)用 EventBridge。SNS 每个主题支持的配信目标(订阅)数量远超 EventBridge(12,500,000 vs 每规则 5 个目标),但 EventBridge 通过规则数量实现扩展。

SNS 的费用

Standard 主题发布每 100 万次约 0.50 美元。FIFO 主题每 100 万次约 0.30 美元。HTTP/S 配信每 100 万次约 0.60 美元,SQS 配信免费。SMS 配信按目标国家的每条消息计费。消息过滤不产生额外费用,通过减少不必要的配信优化下游成本。

总结

SNS 是基于主题的 Pub/Sub 消息服务,通过扇出模式和订阅过滤提供灵活的消息路由。FIFO 主题实现顺序保证和去重,消息数据保护实现 PII 自动检测和遮蔽。与 SQS 组合构建可靠的异步处理管道,DLQ 确保可靠捕获配信失败。