使用消息队列有什么好处呢

消息队列是什么


也许你经常听说"消息队列"这个词,但是并没有真正用过它。它在系统架构中担任着非常重要的角色。那"消息队列"到底是个什么样的东西呢?今天我就来给大家聊聊"消息队列"这个技术。

从字面上分析,首先它有一个队列,其次这个队列里存放的是消息。那队列又是个什么鬼?不要想得太复杂,队列就是一个可以存储数据的"容器",里面你可以存数字、也可以存字符串。

而"消息队列"就是一种专门存放消息数据的一种中间件服务。这个消息其实就是一条一条的数据对象,比如它可以是一个文件路径,也可以是一条订单的信息。

为什么要使用消息队列


在给出答案之前,我先讲一个小例子。

一个小作坊工厂有一道工序,需要给瓶子拧盖子然后贴商标。工人小A擅长拧盖子,工人小B擅长贴商标,所以此道工序由小A和小B配合完成。

一开始小A拧完盖子后交给小B再去贴商标,如果小A已经拧完盖子交给小B时,小B还在贴商标,那么此时小A只能等着小B,只有小B上一次的贴商标动作完成后,小A才能把这次的瓶子交给小B,然后继续拧下一个。

这种配合需要小A和小B的工作节奏完全一致才能不会浪费时间。

老板大黄很聪明,他做了一个可以自动旋转的瓶子架,圆盘形状,最多可以同时放10个瓶子,小A和小B分别坐在圆盘的相对面,他要求让小A拧完盖子后将瓶子放到架子上,然后小B再从架子上去拿小A已经拧完的瓶子。

这样做,就不用担心小A比小B快的问题了,那反过来如果小B比小A快,那就需要先让小B休息一会,让小A先多拧几个瓶子,小B再开始工作。

这样一番操作,大黄发现效率并没有提升,只是把小A或者小B休息的时间延长了。此时老板的解决方法是,如果小A比小B快,则当小A将10个瓶盖子都拧完时,先帮着小B贴标签,反之,小B帮小A拧盖子。

结合这个案例,那么消息队列其实就是大黄设计的自动旋转瓶子架,我们可以把消息放在消息队列中(拧完盖子后放到架子上),当需要消息时,再从消息队列中取出消息处理(小B拿拧完盖子的瓶子去贴商标)。

消息队列是分布式系统中的重要组件,使用消息队列主要是为了通过异步处理提高系统性能和削峰、降低系统的耦合性。

场景1:解耦

所谓解耦,就是将一个事务的多个动作进行拆分,就比如上例中,本来一道工序包括了拧瓶盖(A)和贴商标(B),一开始两个动作是耦合在一起的,耦合在一起意味着A慢或者B慢都会影响到整个工序的效率。那么现在将A和B拆分,A可以只关注拧瓶盖,拧完放到架子上(消息队列里),而B只需要从架子上(消息队列里)去拿即可。只要这个架子容量足够大,那么A和B都不会被对方影响。

再回到消息队列,A和B分别为两个模块,A模块有一个消息生产者,B模块有一个消息消费者。A和B两个模块就是由这个消息队列来完成的解耦合。

场景2:异步

异步,就是要将本来串联的多个操作拆分开,让它们不再相互等待。比如,上例中,A拧完瓶盖不需要等着B是否空闲,他只管拧瓶盖,然后将已经拧好瓶盖的瓶子放到架子上即可,而B也只管从架子上去拿拧好瓶盖的瓶子来贴商标,A和B就是异步的,异步的实现要借助这个消息队列。

再举个实际的例子,一个审计系统,需要将手机客户端上的图片、音频、视频上传到服务器上进行审核,这个过程中有一个步骤是需要将视频、音频进行转码的,转码的目的是为了让多媒体文件更小,让浏览器可以直接播放。上传音频和视频的操作非常频繁并且量很大,如果每上传一个文件就直接转码,那么这不仅会消耗服务器资源,还会直接降低了服务器处理速度。所以,我们的做法是,让它异步。上传和转码分开,不串行,甚至可以让某一台服务器单独处理转码的操作。那么这个实现就需要借助消息队列,把转码任务以及转码关键参数放到消息队列里,而转码服务器再去通过从消息队列里取这些信息从而再去转码。当然,之所以设计为异步有一个前提条件,就是这个转码的操作并不是很紧迫,不需要一上传文件就马上转码。

场景3:削峰

依然是上面的例子,有一天老板大黄接了很多订单,所以他号召一家老小都来工作,但是大家对贴商标不怎么在行,都去拧瓶盖了,所以一上午的时间一下子拧了1w个瓶盖,并放到架子上(假设老板搞了一个非常大的架子)如果按正常工序,肯定需要很多贴商标的人,才能快速消化掉这1w个拧好瓶盖的瓶子,但老板没有那么多员工。最终,只能是让贴商标的工人多加会儿班慢慢消化这些瓶子。

现实生产环境中,这个非常大的架子就是消息队列服务,它可以应对突发情况,可以将突然陡增的业务需求先暂时放到消息队列里,然后再慢慢地消费(处理),这就是削峰。12306的抢票就是这种场景。

结论


消息队列是一个大型分布式架构中不可或缺的组件,它的存在可以让我们的系统支持更大的并发,提高了系统响应速度,使我们的系统更加稳定可靠。总之,引入消息队列组件是利大于弊的。

那么常见的消息队列中间件都有哪些呢?请大家关注我的公众号,后续会一一介绍。

猜你喜欢

转载自blog.csdn.net/am_Linux/article/details/129720206