一、消息队列定义
消息队列MQ (Message Queue),也称为消息中间件,是分布式系统中重要的组件,通过异步处理提高系统性能、削峰和降低系统耦合性等问题,实现高性能,高可用,可伸缩和最终一致性架构。基于消息队列的系统有RabbitMQ, ZeroMQ, Kafka, RocketMQ等。
消息队列的一般模型:
·
二、外卖和消息队列
周末上午11点,小李悠悠转醒,刷了10分钟掘金,终于还是憋不住尿意,忙去厕所迅速解决了一番。后又躺回床上,悠哉游哉玩手机。直到饥肠辘辘,这才随便点了个外卖。
半小时过去,小李突然感到腹部竟有翻江倒海之势,伴随着阵痛,像是有什么东西要呼之欲出。他连忙跑到卫生间,坐到马桶上,刚脱了想要解放就听见裤兜里有什么东西在响。
没错,不管发生了肾么事,手机一定要带上。小李这才反应过来,应该是自己点的外卖到了。租的房子里只有自己一人。
他还是接通了。
夹着双腿,他颤颤巍巍道,“喂。”
“顾客您好,您的外卖到了哦。楼下有门禁,您看我是怎么上来或者给您放哪儿好呢?”
这时候小李就有几种回复选择:
①“抱歉我在拉*,你等个十五分钟,我马上下来”
②“你等着有没有别的业主回来,有的话顺便帮我带上来放到门口”
③ 憋着,拿了再上来
④“楼下有个专门放外卖的台子,帮我放在哪儿吧,记得给我拍个照”
想了想,第一种太粗鲁,有损小李的文质彬彬,并且自己也不能控制拉*的时间。第二种随机性太大。第四种就非常符合人道主义,既解决了他的窘迫,也不浪费外卖小哥的时间,肥肠的优雅。你说为啥不讨论第三种,实在是憋不住啦!
小李理所当然的选择了第四种,用比手速 (指敲代码) 还快的速度说完之后挂了电话。也终于如滔滔江水奔流而下......
·
上述例子简化为消息队列模型:
生产者:外卖小哥,生产了一个外卖的消息
消费者:小李,需要取得外卖的消息
消息队列:外卖台子
若无放外卖的台子,流程阻塞
若有放外卖的台子,即有消息队列,就可以解决时间冲突的问题
以上故事纯属雷同。如有巧合,全是虚构......
三、消息队列优点
1. 解耦
本来小李和外卖小哥是直接进行外卖的交接,但此时外卖小哥送外卖就非常依赖于小李的状态,比如小李正在上厕所、小李突然有事被老板叫去线上会议啊,等等。而有了消息队列外卖台,外卖小哥送外卖受到小李的影响就会大大降低,他只需要将外卖放到外卖台,不需要关心小李是否在拉*。这就是解耦。
生产者和消费者不直接依赖,而都依赖于消息队列。
2. 异步
同步指小李在蹲马桶,没拉完外卖小哥就得一直在楼下等着。异步指小李接到消息后,外卖小哥把外卖放到外卖台,就可以继续去送其他外卖了,不用再等待小李。
同步:生产者发送消息给消费者,需要等消费者接受消息、完成消息内容并给生产者返回响应后,才能继续执行其他任务。
异步:生产者发送消息给消息队列,消息队列可快速响应,生产者接收到消息队列的响应之后就能执行其他任务。消息在消息队列中再传输给消费者进行消费。
3. 削峰
996之后的一个小长假,小李叫了几个朋友来家里,并决定搞点好吃的。点了炸鸡、小龙虾、烧烤、酒水....没多久,外卖小哥电话来了,正巧这几个朋友玩嗨了,只好小李自己下去拿。试想一下没有外卖台,小李刚拿了炸鸡电梯都上一半了,又来了个电话,他只好又下去一次,循环往复,小李被弄得火急火燎。
当然,聪明的程序员小李没有这么憨,他等所有外卖都到了,朋友们开启下一轮游戏的间隙,叫了俩朋友下去帮忙拿外卖,自己在空调房里好不快哉。
若同一时间生产者产生大量消息,会将消息存入消息队列,由消息队列按一定顺序发送给消费者进行消费。若消息队列中消息超过一定数量,则返回给生产者错误信息,多余的消息不会存入消息队列中。
·
四、消息队列模式
1. 点对点模式——不可重复消费
特点:
每个消息只有一个消费者,且一旦被消费,该消息就不再在消息队列中;
生产者和消费者间没有依赖性,发送者发送消息之后,不管有没有消费者在运行,都不会影响生产者下次发送消息;
消费者在成功拉取消息之后需向消息队列应答成功,以便消息队列删除当前消息。
2. 发布/订阅模式——可重复消费
特点:
每个消息可以有多个消费者;
消费者需先订阅某个主题的消息,生产者才会把相应主题的消息推送给已订阅的消费者 (类似微信公众号);
消费者被动接收推送,但当推送速度和消息处理速度不一致时,可能会出现消息堆积或资源浪费等情况。
·
最后的最后,李阿姨和小李温馨提示您:饭前便后要洗手......
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 3 天,点击查看活动详情