面试题剖析
这个问题这么问是很好的,因为不能问你Kafka的高可用这么保证啊?AcitveMQ的高可用这么保证啊?一个面试官要这么问就显得很没水平,人家可能用的就是rabbitMQ,没用过Kafka,这不摆明刁难人家。
rabbitMQ的高可用性
rabbitMQ是比较有代表性的,因为是基于主从做高可用性的,我们以他为例子讲解第一种MQ的高可用性是怎么实现的。
rabbitMQ有三种模式:单机模式、普通集群模式、镜像集群模式
单机模式
就是demo级别的,一般就是你本地启动了玩玩儿,没人生产用单机模式
普通集群模式
先看图
意思就是在多台机器上启动多个RabbitMQ实例,每个机器启动一个。但是你创建的queue,只会放在一个rabbitMQ实例上,但是每个实例都同步queue的元数据,完了你消费的时候,实际上如果连接到另外一个实例,那么这个实例会从queue所在实例上拉取数据过来
这种方式确实很麻烦,也不怎么好,没做到所谓的分布式,就是个普通集群。因为这导致你要么消费者每次随机连接一个实例然后拉取数据,要么固定连接那个queue所在实例消费数据,前者有数据拉取的开销,后者导致单实例性能瓶颈。
而且如果那个放queue的实例宕机了,会导致接下来其它实例无法从那个实例拉取数据,如果你开启了消息持久化,让rabbitMQ落地存储消息的话,消息不一定会丢,但是得等到这个实例恢复了,然后才能继续从这个queue拉取数据。
所以这事就比较尴尬了,这就没什么所谓的高可用性可言,这方案主要是提高吞吐量的,就是说让集群多个节点来服务某个节点的queue的读写操作。
缺点一:可能在集群内部产生大量的数据传输
缺点二:可用性基本没有保证,如果queue所在节点宕机了,也就无法消费消息了
镜像集群模式
先看图
这种模式,才是所谓的RabbitMQ的高可用模式,跟普通集群模式不一样的是,你创建queue,无论是元数据还是queue里的消息都会存在多个实例上,然后你每次写消息到queue时,都会自动把消息同步到多个实例的queue里。
这样的话,好处在于,其中一台服务器宕机后,不影响,坏处在于,第一,性能开销也太大了吧,消息同步到所有机器,导致网络带宽压力和消耗很大!第二,这么玩也就没有扩展性可言了,如果某个queue负载很重,你加机器,新增的机器也包含这个queue的所有数据,并没有办法线性扩展你的queue
那么怎么开启这个镜像集群模式呢?在web后台管理界面新增一个策略,这个策略就是镜像集群策略模式的策略,指定的时候可以要求数据同步到所有的节点中,也可以要求就同步到指定数量的节点,然后你再次创建queue的时候,应用这个策略,就会自动将数据同步到其他的节点上了。