1. RabbitMQ的高可用
      ① 普通集群模式:
      假设rabbitMQ集群有三台机器,每台机器都启动了一个进程作为集群中的一个节点,但是创建的queue只会放在一个rabbitMQ实例上,其他实例都同步queue的元数据(它知道queue在哪),消费者消费时,如果连接到了另一个实例,那么他会从queue所在的实例上拉取数据过来,这个方案没有什么高可用性科研了,主要是提高吞吐量,让集群中多个节点来服务某个queue的读写操作。缺点有两个,一是可能会在rabbitMQ内部产生大量的数据传输,二是可用性几乎没什么保障,如果queue所在的节点宕机了导致queue的数据丢失了,就无法消费了。
      ② 镜像集群模式:
      每个节点都有一个queue的完整镜像,包含这个queue的全部数据,所以叫镜像集群模式。任何一个节点宕机,其他节点上还包含了这个queue的全部数据,消费者可以到其他节点去消费数据。缺点,不是分布式的。

    2. kafka的高可用性
      kafka最基本的架构知识:多个broker组成,每个broker是一个节点,创建一个topic,这个topic可以划分为多个partition,每个partition可以存放在不同的broker上,每个partition就存放一部分数据,kafka0.8以后提供了HA机制,replica副本机制,每个partition的数据都会同步到其他机器上,形成自己的replica副本。然后所有的replica会选举一个leader出来,生产者和消费者都跟这个leader打交道,其他replica为follower。写的时候,leader会将数据同步到follower,kafka会将一个partition的所有replica分布在不同的机器上提高容错性,如果某个broker宕机,那么broker上面的partition在其他机器上的副本都有的,如果这个机器上有某个partition的leader,那么此时会重新选举一个新的leader出来,大家继续读写那个新的leader即可,实现高可用。
      写数据的时候,生产者只写leader,leader在将数据落地本地磁盘,接着其他follower自动从leader来pull数据,一旦所有follower同步好数据了,就会发送ack费leader,leader收到所有follower的ack之后,就会返回写成功的消息给生产者,消费的时候只会从leader读,只有一个消息已经被所有follower都同步成功返回ack时,才会被消费者读到。