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

170 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 第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"是最佳组合?
---
## 延伸阅读
- [SQS 开发者指南](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/)
- [SNS 开发者指南](https://docs.aws.amazon.com/sns/latest/dg/)
- [AWS 消息传递模式](https://aws.amazon.com/messaging/)
---
## 明天预告
明天是第二阶段的收尾:用一个完整的项目案例,把这 11 天学到的所有核心服务串联起来,看看它们在真实架构中是怎么配合工作的。