https://xie.infoq.cn/article/8085241414e8959323ecd7811
我们来将快递柜与消息队列做一个对比
消息队列比作快递柜:有很多厂家生产快递柜,如:丰巢(apache kafka),速递易(alibaba RocketMQ),近邻宝(ActiveMQ)等等,反正常用的就这几个。快递柜负责临时保存邮件,消息队列负责临时保存消息数据。
快递员比作消息生产者:快递员负责向快递柜投递邮件,生产者负责向消息队列投递消息。异曲同工之妙啊!
消费者比作消息消费者: 可能是这个例子太贴切了,以至于这句怎么看都是废话。废话也还是要说,生活中的消费者取邮件,程序中的消费者取消息数据。
我们先回顾一下在没有快递柜的日子里是怎么度过的:某天早上突然接到快递员电话:"兄弟,有你的快递啊"。心里想真糟糕:“你早不来晚不来,我马上就要上班了,你这个时候来。好吧,我等你一会”。结果有可能快递员很不靠谱,一会说堵车,一会说马上到,等来等去你上班迟到了。这种情况让你很崩溃!
突然有一天,小区里突然出现了一个叫做快递柜的东西,这东西好啊。"兄弟,有你快递啊",心想谁是你兄弟:"啊,你放快递柜里面吧,我晚上下班回来取"。快递员愉快的把快递放入快递柜,开始打下一个电话,一早上 10 个邮件。如果每个都送上门快递员最少要半小时。现在好了,9 个放快递柜,1 个用户要求送上门,10 分钟就搞定了。快递员觉得这个东东真的很好!
快递员高兴了,消费者用户其实也很满意,有的购物狂一天有可能收 10 来个邮件。没有快递柜的时候,快递员来一个电话就去取一次(等一次)快递。有了快递柜,下班的时候就一起全都取了。上面的例子,体现了消息队列(快递柜)的几个优越性,请读者仔细品评:
异步解耦:有了快递柜,消费者不用等待快递员,用户体验增强。消费者与生产者(快递员)之间解耦,不会因为对方的操作行为,影响自己独立处事的程序。用户不用疲于等待与接收事件阻塞耗时。
流量削峰:我们假定一种极端的情况,你通过各个渠道买了 1000 本书,突然某一小时集中的给你打电话。你肯定不具备一个小时收 1000 个邮件的能力,所以你让快递员将邮件放入快递柜。所以你就可以按照自己的处理能力,按照自己的时间安排去取邮件。同样我们的消费者程序在面临多用户、高并发的请求情况下,将数据放入消息队列保存可以将流量数据削峰,按照程序能够处理的能力和资源进行数据消费。
缓冲批处理:生产者批量投递,爽!消费者一次性取多个邮件,爽!
说了这么多的优点,那么快递柜有没有缺点呢?当然有
引入复杂度。毫无疑问,快递柜(消息队列)这东西是多出来的,在原来的收取过程中是不存在的。所以需要地方放它,还需要防火、防盗防潮,需要去维护它。消息队列中间件也是一样的,你需要服务器区安装它,还要对它进行维护。
会导致暂时的数据不一致。 如果没有快递柜,你收到了邮件件就是真的收到了。但是使用快递柜之后,你收到了"邮件放入快递柜的消息",但是与你真的取到邮件这中间会有一定的延时。当然你最终还是会取到邮件,选择"消息队列"快递柜,就是要忍受暂时不一致,接受"最终一致性"。
当然极端情况下,快递柜坏了,你要不可避免地接受"邮件可能会丢失"的事实,对于安保系数高的小区这几乎不会发生。