aws-doc/课程/第二阶段-核心服务/第18天-SQS与SNS消息服务.md
2026-05-08 10:24:39 +08:00

6.0 KiB
Raw Blame History

第18天SQS 与 SNS——消息队列和通知服务

今天你将学到什么

今天学习两个让系统"松耦合"的服务SQS消息队列和 SNS通知服务。它们解决的核心问题是让系统的各个部分不再紧密依赖,一个部分出问题不会拖垮整个系统。


为什么需要消息队列——用餐厅来理解

没有消息队列的世界(紧耦合)

想象一个餐厅,流程是这样的:

顾客点单 → 服务员站在厨房门口等 → 厨师做好菜 → 服务员端菜上桌 → 服务员回来接下一个顾客

问题

  • 服务员在等厨师做菜的时候什么都干不了(阻塞)
  • 如果厨师突然肚子疼去了厕所,服务员和顾客都得干等(一个环节故障影响全部)
  • 午餐高峰期 100 个人同时点单,厨房根本忙不过来(没有缓冲)

有消息队列的世界(松耦合)

改进后的流程:

顾客点单 → 服务员把订单贴在窗口(消息队列)→ 服务员立刻回去服务下一个顾客

厨师按自己的节奏从窗口取订单做菜 → 做好了放在出菜口 → 服务员来取

好处

  • 服务员不用等厨师(异步,不阻塞)
  • 厨师去厕所了?订单还贴在窗口,回来继续做(容错)
  • 高峰期订单堆在窗口,厨师按自己的速度做,不会崩溃(削峰)
  • 可以加更多厨师来加快速度(水平扩展)

这就是消息队列的价值。


SQSSimple Queue Service

SQS 是 AWS 的消息队列服务——一个"订单窗口"。

工作流程

生产者(发送消息的人)→ SQS 队列 → 消费者(处理消息的人)

举个真实例子:电商下单流程

用户点击"提交订单"后,需要做很多事:

  1. 扣减库存
  2. 发送确认短信
  3. 生成物流单
  4. 更新用户积分
  5. 通知仓库备货

没有 SQS:所有步骤串行执行。用户要等所有步骤完成才看到"下单成功"。任何一步失败,整个订单失败。

有 SQS

  • 订单创建成功后立刻返回"下单成功"给用户(用户不用等)
  • 同时把"有新订单"这个消息发到 SQS 队列
  • 库存服务、短信服务、物流服务各自从队列取消息处理
  • 某个服务暂时挂了?消息还在队列里,恢复后继续处理

SQS 的关键特性

消息保留:消息最多保留 14 天。如果 14 天内没人处理,才会被删除。

可见性超时:消费者取走一条消息后,这条消息对其他消费者"隐藏"一段时间。如果消费者处理成功就删除消息;如果处理失败(比如消费者崩溃了),超时后消息重新出现,可以被其他消费者重试。

死信队列:如果一条消息反复处理失败(比如重试了 5 次都失败),自动转移到"死信队列"。你可以人工检查这些"问题消息",避免它们阻塞正常处理。


SNSSimple Notification Service

SNS 是"发布/订阅"模式的通知服务——一条消息可以同时发给多个接收者。

SQS vs SNS 的区别

SQS = 点对点(一条消息只被一个消费者处理)

  • 类比:快递柜。一个包裹只能被一个人取走。

SNS = 广播(一条消息发给所有订阅者)

  • 类比:小区广播。一条通知所有住户都能听到。

SNS 的工作方式

发布者 → SNS 主题Topic→ 订阅者 A邮箱
                           → 订阅者 B短信
                           → 订阅者 CSQS 队列)
                           → 订阅者 DLambda 函数)
                           → 订阅者 EHTTP 接口)

举个例子:用户注册成功后

用户注册成功 → 发布"新用户注册"事件到 SNS
    → 邮件服务收到 → 发送欢迎邮件
    → 积分服务收到 → 赠送新人积分
    → 推荐服务收到 → 生成个性化推荐
    → 数据分析收到 → 记录注册统计

一个事件,多个服务各自处理自己关心的部分。互不影响。


经典组合SNS + SQS扇出模式

这是 AWS 最推荐的异步架构模式:

订单服务发布"新订单"事件
    ↓
SNS 主题(广播给所有订阅者)
    ├── SQS 队列 A → 库存服务(扣减库存)
    ├── SQS 队列 B → 通知服务(发短信/邮件)
    ├── SQS 队列 C → 物流服务(生成运单)
    └── SQS 队列 D → 积分服务(加积分)

为什么中间要加 SQS不直接用 SNS 推给各服务?

因为 SQS 提供了"缓冲"和"重试"

  • 某个服务暂时挂了 → 消息在 SQS 里等着,恢复后继续处理
  • 某个服务处理慢 → 消息在 SQS 里排队,不会丢失
  • 流量突然暴涨 → SQS 帮你削峰,各服务按自己的速度消费

同步 vs 异步:什么时候用哪种

场景 方式 原因
用户查询商品详情 同步 用户在等结果,必须立刻返回
用户下单扣库存 同步 必须确认库存够才能下单
下单后发确认短信 异步 短信晚几秒发不影响下单结果
下单后更新推荐 异步 推荐更新慢一点无所谓
上传图片后生成缩略图 异步 缩略图不需要立刻生成

判断标准:用户是否在等这个结果?如果是,同步。如果不是,异步。


今天的小测验

  1. 消息队列解决的核心问题是什么?用你自己的话解释。
  2. SQS 和 SNS 的区别是什么?各自适合什么场景?
  3. 什么是"死信队列"?它解决什么问题?
  4. 为什么说"SNS + SQS"是最佳组合?

延伸阅读


明天预告

明天是第二阶段的收尾:用一个完整的项目案例,把这 11 天学到的所有核心服务串联起来,看看它们在真实架构中是怎么配合工作的。