摘自杰瑞 · 赫尔曼的《你好,多莉》歌曲: 人性一个最特别的弱点就是:在意别人如何看待自己。 —亚瑟・叔本华-

消息队列

内容目录

消息队列

1. 消息队列是什么?

消息队列(Message Queue)简称MQ,顾名思义就是传递消息的队列,既然是队列,就有着先入先出的原则。同时还具备着可靠性,高性能等特点。

消息队列是大型分布式系统不可缺少的中间件,一般用于异步流程、消息分发、流量削峰等问题,可以通过消息队列实现高性能、高可用、高扩展的架构。

业界比较出名的消息队列有ActiveMQ、RabbitMQ、ZeroMQ、Kafka、MetaMQ、RocketMQ。其中Kafka较为流行。

2. 消息队列应用场景?

消息队列的本质是解决消息传递的问题,其他场景都是扩展出来的。

解耦

解耦就是解除耦合,比如两个服务A如果需要等待B的返回,关注返回的结果和数据,或者就是单纯要B服务处理后,A才能给更前端返回,这就是耦合。

比如:发送短信场景,假设服务SevA发送消息给SevB,SevB发送短信给客户,很多时候业务是允许SevA不需要得到SevB发送完成的回应,只需要消息发送到SevB就行了,这种情况下,如果还让SevA等待SevB的返回,显然会导致性能变低,同时还要去关注SevB的运行结果。
所以,如果业务上可以去除这种依赖,那么就会获得性能、可靠性等的提升。

异步

如果一个接口,处理时间很长,而且不能通过水平扩容来解决,就需要异步,那么,什么情况下不能通过水平扩容解决呢?
有很多,比如视频处理,涉及到视频下载,那受限于网络带宽等因素,扩容无用;比如区块链这种共识场景,只有单机才能出块,扩容也没有用;还有更常见的,比如一个业务流程,过了10多个微服务,单个也许不长,加起来就很难接受。
以上的情况下,用户很难通过同步接口长时间等待结果,那就应该做成异步,先扔进消息队列,后续再进行消费,和解耦一样可以收获更高的性能,以及获得更好的可靠性。
异步和解耦最大的区别在于:解耦是业务上本身就不需要依赖,异步是可能还是需要关注结果,但是不一定干等,可以回头再找。

消息分发

假设一个核心服务A,是用来发布某种信号的,发布之后,需要通知到下游服务B、C,这种模式在只有B、C两兄弟的时候,没啥问题。
但随着业务需要,可能会有D、E、F等更多的打工人出现,这时候A服务就需要更改代码,将消息也传递给这些新加入的兄弟,每次增加打工人,就需要更改一次代码。

而引入消息队列,则可以解决这个问题,实现能力复用,业务解耦,拥有了高扩展性。

削峰

每天跑40km,1小时之内跑完40km可能人就挺不过去了,但是分散到20小时,1小时2km,就能存活,这就是削峰。
我们经常遇到的秒杀场景就需要削峰的能力,一般而言就是将扣减库存操作均匀化处理,以防止瞬时流量打崩MySQL。

其实在架构上,削峰和上面的异步场景是相同的架构,都是将请求扔入队列中,再慢慢消费。
但要注意异步场景更偏向于单个请求,本身处理时间很长。削峰针对是单个请求ok,但是流量突发扛不住的场景。

总结:

消息队列本质是解决消息传递的问题,后端设计领域其实不是组件用得越多越好,而是非必要尽量简化,所以一定要有合适的特定场景,才引入消息队列,常见场景有解耦、异步、消息分发、与削峰

发表评论