快速导航
面试题:
- 为什么使用消息队列?
- 消息队列的优缺点?
- Kafka、ActiveMQ、RabbitMQ、RocketMQ 的区别和适合的场景?
为什么使用消息队列?
回答这个问题,为什么要使用消息队列?
答案肯定是因为使用它有好处,或是能解决业务痛点、或是能提升系统性能、或是能提升开发效率。
而使用消息队列能做到:解耦、异步、削峰
1. 解耦
作为一个开发人员,想必我们对设计原则多多少少也有一些了解,高内聚低耦合是软件工程中对设计好坏判断的一个标准。
这里说的解耦的意思,就是降低耦合度。
想象一下,系统A同时和系统B、C、D等多个系统存在业务联系,使用的最简单的方式,就是接口直接调用。
这个过程有两个特点:同步 和 阻塞
系统A对数据的修改,实时同步更新到B、C、D系统中,且在同步过程中,系统A在当前线程中不能做任何其他的操作。
- 一旦同步过程出现一点点的问题,则整个系统的业务就无法继续进行下去。
- 新增或者删除同步的系统(系统D不需要更新系统A的状态了,新系统E需要根据系统A的状态同步更新),都需要修改系统A的接口调用代码,这违反了开闭原则。
而使用MQ作为一个消息的缓冲区,系统A把所有对其他系统的同步通知消息都交给MQ,然后再由需要消息的其他B、C、E系统消费消息,可以有效的降低系统之间的耦合度。避免系统A调用其他系统时可能出现的全部系统奔溃。
2. 异步
在解耦的部分,已经对系统间的调用过程有了讲解,其中一个特点就是:同步
同步的一个好处是,简单。
这个好处是站在开发人员的角度上来说的,一个请求调用链路的代码一气呵成。
但是在用户看来这样真的好吗?
回答这个问题之前,可以想想对用户来说最重要的是什么?
响应速度,一个页面刷新的时间是10ms,另一个页面刷新的时间是10s,用户更倾向于哪个想必显而易见了。
假设一个场景,系统A接口请求时间是5ms,调用系统B耗时500ms、调用系统C耗时350ms、调用系统D耗时200ms。(为什么耗时差距这么大?可能是代码质量问题、可能是网络问题,谁说的准呢?)
那么使用接口调用的总耗时是多少呢?
sum = 5ms + 500ms + 350ms + 200ms = 505ms(别问我是怎么算出来的这个数,问就是多线程调用,水桶理论)
而加入MQ的效果呢?
系统A将消息交给MQ后,就标志着这次请求成功了。
总耗时是:
sum = 5ms + MQ (我只管把消息给MQ,由MQ保证消息的可靠性和可用性) = 5ms
这就是异步调用的好处。
3. 削峰
削峰,削的是什么峰?
答:流量的峰,http请求的峰,数据的峰
两种众所周知的场景:
双十一抢购/春运抢票:同一时刻会有几百万上千万甚至上亿的下单请求
在用户看来顶多是没抢到,但是在系统运维人员的眼中,这不只是破天的富贵,而且是惊心动魄的生死时刻。
我们常用的MySQL也好,Oracle也好,都是处理能力的上限的。每秒几K,甚至几十K的数据处理能力,也就差不多了。
那么在上面的两种场景下,会发生什么现象呢?
数据库直接奔溃,世界一片黑暗。 为什么世界黑暗了?因为你的眼中冒着星星了。
那么怎么解决这个问题呢?好巧不巧的,MQ出场了。
淘宝/12306的订单请求来了,任你是每秒多大的请求,通通交给我MQ缓冲起来。你来多少请求,我不一定非要立即同时就给你处理。就像你去银行办业务,银行只有5个窗口,你带着100个人,那不可能同时给你这100个人办理呀。
怎么办?
就让你排队吧,按你们进门的时间先后,排个5队,业务员依次处理。
MQ的全称就是消息队列,是不是豁然开朗了?它就是一个队列么。
在系统中加入MQ之后,就不需要关注每秒来多少请求了。
消息队列的优缺点?
前面讲为什么使用MQ,已经讲了它的优点。
这里再说说它的缺点:
1. 系统可用性可能会降低
可用性降低这个情况,和业务有关。
若系统A同步的系统数量很多的时候,任何同步都可能出现问题,本身可用性就会降低。
使用MQ之后,无非是多了一个外部依赖,影响微乎其微,但是当MQ挂掉之后,整个系统都将奔溃,这是我们所不能承受的。
所以就需要考虑MQ的高可用。
2. 系统复杂度提高
系统架构加进来了MQ,对其他的业务系统A、B、C等来说是减负了,但是责任总得有人承担呀。
在架构设计时,我们假定的情况就是MQ是可用的,交给MQ的消息都以符合我们心意的方式来为其他系统提供服务。
但是实际中,消息的重复消费、消息丢失处理、保证消息顺序传递 等都是需要考虑的问题
3. 一致性的挑战
使用系统间接口调用的方式,所有的系统调用都是同步的,状态始终是一致的。
而加入MQ以后,系统A将消息交给MQ之后,就宣告请求处理成功。但其他需要消费MQ中消息的系统,可能遇见MQ宕机、系统自身处理失败等问题,这就导致了数据的不一致。使用MQ时需要注意!
Kafka、ActiveMQ、RabbitMQ、RocketMQ 的区别和适合的场景?
区别:
使用建议:
- ActiveMQ:诞生的比较早,缺乏大规模吞吐量的验证,社区不活跃,不推荐使用
- RabbitMQ:使用erlang开发,开源,支持稳定,社区活跃,中小型公司推荐
- RocketMQ:阿里出品,现在捐给Apache了,社区和github活跃度差点意思,公司技术实力强推荐
- Kafka:大数据领域实时计算、日志采集等场景的业界标准,社区活跃,必用。