「生命不息,折腾不止」
介绍
消息队列的应用场景十分广泛,主流的消息中间件有ActiveMQ,RabbitMQ,RocketMQ,ZeroMQ,Kafka等,ActiveMQ是最老牌的MQ,它是Apache的开源项目,ZeroMQ是最快的消息队列,RabbitMQ也很不错,RocketMQ是阿里巴巴的开源项目,现在已经捐赠给Apache并成为了Apache的顶级项目,Kafka是吞吐量最高的消息中间件,常用于日志的处理,可能因为吞吐量的原因,ActiveMQ和RabiitMQ的活跃度越来越低,RocketMQ因为有相当好的性能,抗过了阿里的双十一,双十二等,所以越来越活跃,但是别去管那么多,消息中间件都差不多,懂一个了去学其他的也都一样
应用场景
MQ的应用场景很多,主要的是,异步,削峰,解耦,这一点应该烂熟于心,下面具体说一说每一个特性
异步
举个用户注册的例子,当用户注册时输入信息提交注册后,一般的系统可能会发短信到绑定的手机,还有邮箱等等,这个过程大概是这个样子,先将用户的信息保存到数据库,然后调用短信接口,再调用邮箱接口,最后返回注册成功信息给客户端,图示如下。
如上图,一个注册实际上是经过了很多个流程,当然,在比较小的系统里根本不会有啥问题,但是试想一下,如果我的系统突然迎来大量的人注册(火了),几千几万的来,那肯定会带来很多问题,加上如果网络拥塞等问题,可能注册一下要好久才能返回,或者数据库直接宕掉都有可能,带来的用户体验一点也不好(我他妈还没有注册,你就让我如此失望,我们还是不适合),为了留住用户,所以很有必要引入消息队列,引入后我们再来看一看架构。
引入了消息队列后并不像以前那样顺序执行了(等一个业务先完成,再到下一个),而是通过异步的方式去执行了,我将用户的注册信息投入到消息队列,大家一同去消费,不仅缩短了时间,还避免了许多问题,
解耦
啥也不说,直接上个例子,比如我有一个购物系统,它下面有很多子业务,积分啊,库存啊,优惠卷啊,部门等等,当我要要增加一个物流的接口,那么在没有用消息队列的情况下新增一个接口,我又要去改规则,改代码,这他妈谁受得了,一两个还可以,你来几十个,那老子直接跑路了,谁爱干谁去干,老子干不了,如图
如上所示我们看到了弊端,在社会高速发展的情况下,业务是不停在变化的,所以有需求就要改,一直改,一直改,这谁顶得住,这时候,消息队列就派上用场了,加入消息队列后,我们看看有什么变化
从上图可以看出,业务就不耦合了,你有什么需求,我直接发布到消息队列,你订阅了我,你自己拿去用,至于你能不能用,那是你自己的问题,和我这个系统没关,因为我提供了你想要的东西,你不能用是你自己的问题,哈哈,虽然说得有点不负责任,但是这完全是事实,
削峰
在这样一个高并发的时代,随着用户的增加,并发量越来越大,数据库的承受能力有限,所以消息队列起到了一个缓冲区的作用,比如一个秒杀系统,在某个秒活动中,同时有5000个人进行秒杀(要根据系统的用户量,像淘宝双十一1秒差不多60万),如果没有引入消息队列,全部请求落到MySQL上,MySQL可能瞬间宕掉(要根据服务器的处理能力),可能你会说加入Redis作为缓存,但是我们说了,任何数据库(关系型和非关系型)都有它的承受能力,而且并不是所有东西都适合放进Redis,所以这时消息队列就扮演了重要的角色,我们看一看没引入消息队列时的情况。
可以看出所有请求都掉在DB上,DB不死谁死啊,显然这样不行,我们看看引入消息队列后的样子
从上图可以看出我们五年引入消息队列后,所有的用户请求并不是全部投放到数据库,而是投放到MQ,然后再投放到消息队列,因为队列是有顺序的,所以就减轻了数据库的压力, 还可以设置队列值的长度,只允许多个消息进入,这是允许的,因为这个社会本来就是弱肉强食的社会,还需要有一定的运气,如果运气不好,在进入消息队列时队列满了,那就是命吧,没有抢到,如果运气好,是第一个进入队列的,那么恭喜你秒杀成功,最好再去买张彩票,说不定就暴富了!
利弊
凡事有好有坏,有得有失,在你得到的时候其实已经在失去,你有女朋友了虽然不再孤单寂寞了,但是你失去了自由。
使用中间件带来的问题
- 系统的复杂度在上升:比如消息的重复消费,消息的丢失等一堆问题。
- 高可用:比如MQ挂了,我怎么保证消息不丢失,这种问题肯定要搭建MQ集群来保证高可用性
- 事物:怎么保证数据的一致性,肯定要用事物,使用了MQ以后,其实就是分布式事物了,所以还要解决分布式事物这一问题
我们可以看出引入了消息对了其实会有很多问题,上面只是主要的几个,有得必有失,拥有爱情就会丧失自由,想要放纵就必须付出代价