1.背景介绍在这篇文章中,我们来谈谈消息中间件高可用架构的一些原则。对于一个合格的高级Java工程师来说,肯定会遇到系统使用MQ(消息队列)的场景。那么这个时候就需要根据自己的业务场景和需求,来考虑在使用MQ的时候可能会遇到的一些技术问题。然后,你要针对这些技术问题设计一个完整的技术方案。你需要从消息的订阅方式、消息的生产到消费的全链路不丢包、消息中间件本身如何来考虑你的系统和MQ打通后的完整技术方案确保高可用性。因此,本文将谈谈消息中间件高可用的架构原则。2、我们先考虑一下消息中间件的可用性。我们抛开各种具体的技术,想一想MQ的可用性是什么?看看下图,道理其实很简单。假设你的MQ部署在一台机器上,一般情况下,生产者会发送消息给MQ,然后让消费者去获取。但是万一哪天出现了意外情况,MQ部署的机器由于莫名其妙的原因挂掉了MQ本身的进程,或者机器直接宕机了,那么这个时候怎么办呢?很尴尬,不是吗?结果是显而易见的。生产者发不出数据,消费者也拿不到数据。那么整个系统就完事了?因为系统的核心进程根本跑不通吧?MQ宕机会直接导致您的系统自身出现故障,进而可能导致您公司对外的APP、网站等产品无法运行,用户无法使用您公司的服务。如果你的公司是电商平台、外卖平台、社交平台。那么如果发生这种情况,公司岂不是损失惨重?如果你的系统几个小时都不能让人使用,而你公司的电商平台每天的收入可以达到一个亿,但是现在几个小时下不了单,最后一天的收入是5000万,那么你们公司是不是直接亏了5000万?这真的不是开玩笑。如果你关注互联网行业的新闻和八卦,你应该知道,近年来一些大型互联网公司也出现过类似情况,损失惨重。作为码农,我们总得祭祀上天吧?3.集群部署+数据冗余很好,但是问题来了!现在大家觉得一个MQ中间件应该如何实现高可用呢?这里有很多方式,比如数据多副本冗余和集群镜像同步机制。我们先抛开具体的技术,从本质上思考一下MQ集群实现高可用的几种方式。让我们看看下面的图片。假设我们写入MQ的数据是冗余多副本的,即你写的每条消息都复制到其他机器上。所以此时,任何一台机器宕机似乎都不会影响我们继续与MQ通信,写入的数据似乎还在。上图中,MQ以集群方式部署在两台机器上,然后生产者向其中一台机器写入消息,消息自动同步复制到另一台机器。这时候数据在两台机器上,有两份。那么如果第一台机器宕机,对我们有影响吗?答案是不。因为数据本身是冗余多副本的,此时消费者可以消费第二台机器的消息,生产者可以继续向第二台机器写入消息,不会丢失数据。而且,系统可以在完全不中断进程的情况下继续运行,如下图所示。这种感觉是不是很棒?其实这种MQ集群部署架构和数据多副本冗余机制都是很常见的高可用架构。优秀的消息中间件Kafka就是采用这种架构来保证高可用和数据容错。4.多副本同步复制的强制性要求但是这里你要考虑另外几个问题。第一个问题,你在写数据到其中一台机器的时候,有没有这样的需求:必须让那台机器把数据拷贝到另一台机器上,并且保证集群中必须有这个数据的双副本,可以这样写才算成功?没错,如果你不能保证这一点,比如你把数据写到其中一台机器上,还没来得及复制到另一台机器上,第一台机器就直接宕机了。此时,虽然可以继续基于第二台机器发送和消费消息,但是刚刚发送的消息丢失了。看看下面的图片来理解这个场景。所以在使用这种机制的时候,必须要让producer传递一些参数设置,保证一条消息写到某台机器上,并且消息必须成功同步到另一台机器上。等到集群中出现双副本,就可以认为消息写入成功了。只要一台机器刚写完就宕机了,如果它还没有来得及复制到另一台机器,这个写操作就会失败并报错。然后,您应该再次尝试向MQ集群写入数据。看看下面的图片。只要写成功一次,就保证同步数据是双份的。这时候,即使一台机器宕机,数据也不会丢失,生产和消费可以有条不紊地继续进行。5、多机托管、多副本是必须的。第二个问题,如果你的集群有两台机器,现在其中一台宕机了,只剩下一台机器,你还能让你的生产者继续往唯一的机器上写数据吗?答案是不。因为,如果集群中只有一台机器可以处理写入,如果剩下的机器再次宕机怎么办?还会不会造成数据丢失,集群挂掉?因此,您的生产者也应该根据参数进行设置。集群中必须有两台以上的机器可以接收您的数据副本。否则,如果只有一台机器可以接受你的数据副本,那就算了。看看下面的图片,感受一下场景。假设集群中有3台机器,其中一台宕机了。后面写另一台的时候,可以判断集群中还剩下两台机器,足以保证数据双副本的高可用和容错。这样就可以继续正常向MQ集群写入数据了。事实上,上面提到的整套机制都可以在Kafka中使用。它有一些相应的参数,可以配置数据的多份拷贝,包括每次写入必须拷贝多少台机器才算成功,否则要重发。也可以通过参数设置。在继续写入数据之前,集群中的其余机器必须能够托管多个副本。通过这一整套方案的设计和基于特定技术的实现,可以保证在集群部署的情况下,集群中必须有几台机器承载多份,同时冗余写入数据后必须保证多副本。此时,任何一台机器宕机,数据都不会丢失,系统可以继续正常运行。6、架构原理与技术无关其实本文对消息中间件的集群高可用架构的讨论是完全脱离于具体的技术。从本质原则的层面来讨论这个话题是很简单的。RabbitMQ、Kafka、RocketMQ等各种消息中间件在这种高可用架构的实现上有一定的相似性,但也有不同的技术实现和相应的区别。
