# 第18天:SQS 与 SNS——消息队列和通知服务 ## 今天你将学到什么 今天学习两个让系统"松耦合"的服务:SQS(消息队列)和 SNS(通知服务)。它们解决的核心问题是:**让系统的各个部分不再紧密依赖,一个部分出问题不会拖垮整个系统。** --- ## 为什么需要消息队列——用餐厅来理解 ### 没有消息队列的世界(紧耦合) 想象一个餐厅,流程是这样的: 顾客点单 → 服务员站在厨房门口等 → 厨师做好菜 → 服务员端菜上桌 → 服务员回来接下一个顾客 **问题**: - 服务员在等厨师做菜的时候什么都干不了(阻塞) - 如果厨师突然肚子疼去了厕所,服务员和顾客都得干等(一个环节故障影响全部) - 午餐高峰期 100 个人同时点单,厨房根本忙不过来(没有缓冲) ### 有消息队列的世界(松耦合) 改进后的流程: 顾客点单 → 服务员把订单**贴在窗口**(消息队列)→ 服务员立刻回去服务下一个顾客 厨师按自己的节奏从窗口**取订单**做菜 → 做好了放在出菜口 → 服务员来取 **好处**: - 服务员不用等厨师(异步,不阻塞) - 厨师去厕所了?订单还贴在窗口,回来继续做(容错) - 高峰期订单堆在窗口,厨师按自己的速度做,不会崩溃(削峰) - 可以加更多厨师来加快速度(水平扩展) **这就是消息队列的价值。** --- ## SQS(Simple Queue Service) SQS 是 AWS 的消息队列服务——一个"订单窗口"。 ### 工作流程 ``` 生产者(发送消息的人)→ SQS 队列 → 消费者(处理消息的人) ``` **举个真实例子**:电商下单流程 用户点击"提交订单"后,需要做很多事: 1. 扣减库存 2. 发送确认短信 3. 生成物流单 4. 更新用户积分 5. 通知仓库备货 **没有 SQS**:所有步骤串行执行。用户要等所有步骤完成才看到"下单成功"。任何一步失败,整个订单失败。 **有 SQS**: - 订单创建成功后立刻返回"下单成功"给用户(用户不用等) - 同时把"有新订单"这个消息发到 SQS 队列 - 库存服务、短信服务、物流服务各自从队列取消息处理 - 某个服务暂时挂了?消息还在队列里,恢复后继续处理 ### SQS 的关键特性 **消息保留**:消息最多保留 14 天。如果 14 天内没人处理,才会被删除。 **可见性超时**:消费者取走一条消息后,这条消息对其他消费者"隐藏"一段时间。如果消费者处理成功就删除消息;如果处理失败(比如消费者崩溃了),超时后消息重新出现,可以被其他消费者重试。 **死信队列**:如果一条消息反复处理失败(比如重试了 5 次都失败),自动转移到"死信队列"。你可以人工检查这些"问题消息",避免它们阻塞正常处理。 --- ## SNS(Simple Notification Service) SNS 是"发布/订阅"模式的通知服务——一条消息可以同时发给多个接收者。 ### SQS vs SNS 的区别 **SQS = 点对点**(一条消息只被一个消费者处理) - 类比:快递柜。一个包裹只能被一个人取走。 **SNS = 广播**(一条消息发给所有订阅者) - 类比:小区广播。一条通知所有住户都能听到。 ### SNS 的工作方式 ``` 发布者 → SNS 主题(Topic)→ 订阅者 A(邮箱) → 订阅者 B(短信) → 订阅者 C(SQS 队列) → 订阅者 D(Lambda 函数) → 订阅者 E(HTTP 接口) ``` **举个例子**:用户注册成功后 ``` 用户注册成功 → 发布"新用户注册"事件到 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 天学到的所有核心服务串联起来,看看它们在真实架构中是怎么配合工作的。