[TOC] #### 1. 回顾上一讲 --- 上一讲我们列了同步调用的四大问题:强耦合、资源浪费、雪崩风险、扩展困难。 那怎么解决呢 ?你可能已经听过三个词:异步、解耦、削峰。 很多人第一次接触这三个概念的时候,会觉得它们是三个独立的能力,好像要分别实现。 其实并不是,当一条消息进入队列之后,这三个能力往往 同时具备。它们不是三件东西,而是同一件事情的三个侧面。 下面一个一个来说。 #### 2. 异步:不用等,先走 --- 异步这个词,字面意思就是「不同步」——你不用等我做完,你先干你的。 第一讲我们算过一笔账:下单流程里,发短信、发邮件、通知物流加起来要 1 秒。 但这 1 秒的工作,用户真的需要等吗?答案是:不需要。 用户点完「下单」,他只想看到「订单创建成功」,至于短信什么时候发、邮件什么时候到,他根本不关心。 可以把这三步从主流程里拿出来丢进队列,让后台慢慢做。用户只等扣库存和创建订单那 50ms,剩下的事情系统自己消化。 异步的本质:把「等待」从用户身上转移到系统身上。 #### 3. 解耦:别绑在一起 --- 解耦说白了就是:你做你的,我做我的,别互相牵连。 现在的代码里,订单系统直接调用短信、邮件、物流三个系统。 它必须知道这些系统的接口地址、调用方式、参数格式。以后加一个积分系统,代码得改,加一个优惠券系统,还得改。 更麻烦的是,短信系统挂了,可能连订单都创建不了,明明没关系的两个系统,被绑在了一根绳上。 #### 4. 削峰:慢慢来,别崩 --- 削峰填谷,说白了就是:流量突然大的时候,别让数据库直接扛,先排队。 秒杀开始的那一瞬间,1 万个请求同时涌入,如果直接打到数据库,连接数爆满,CPU 100%,直接崩了。 加一个队列呢 ? 1 万个请求涌进来,队列照单全收,先存着,后台消费者按照数据库能承受的速度,慢慢取出来处理。 数据库永远只看到稳定的流量,不会被瞬间峰值打崩,把尖尖的山峰削平,变成缓坡。 #### 5. 它们其实是同一件事 --- 说了这么多,你有没有发现一个规律 ?异步、解耦、削峰,靠的都是同一个东西:队列。 消息进了队列: + 用户不用等 → 异步 + 系统互不依赖 → 解耦 + 流量先排队 → 削峰 不是分别做了三件事,而是加了一个队列,三个问题一起解决了。 所以你不需要记三个概念,只需要记住一件事:在系统之间加一个队列,很多问题自然就解决了。 #### 6. 本文小结 --- | 能力 | 解决的问题 | 一句话解释 | | ------------ | ------------ | ------------ | | 异步 | 用户等待时间长 | 后台慢慢做,用户不用等 | | 解耦 | 系统之间互现牵连 | 你发你的消息,谁需要谁来取 | | 削峰 | 瞬间流量打崩数据库 | 先排队,慢慢处理 | 三个概念,一个核心:队列。但问题来了: + 这个「队列」到底是什么?为什么在系统中间加这么一个组件,就能解决这么多问题? + 它和数据库有什么区别?和 Redis 的 List 有什么区别?为什么不能用数据库模拟一个队列? 下一讲,我们来正式聊聊:消息队列到底是什么,它具体解决了哪些问题。