当前位置: 首页 > 后端技术 > PHP

rabbitmq分布式集群学习

时间:2023-03-29 22:52:14 PHP

集群部署方式rabbitmq一共有三种部署分布式集群系统的方式。ClusterFederationShovel开始学习Cluster。我们通常使用单机模式进行本地开发。这仅供本地使用。生产环境一般是Cluster集群。Cluster集群一般分为两种,普通集群模式和镜像集群模式。使用cluster集群一般有一些前提:属于同一网段的LAN节点不支持跨网段Rabbitmq和erlang版本需要相同不同rabbitmq节点使用的'.erlang.cookie'需要consistent理解一些概念。节点类型磁盘节点(disc):在磁盘中存储元数据,单节点系统只允许磁盘类型的节点,以防止RabbitMQ重启时系统配置信息丢失。·内存节点(ram):内存节点将队列、交换机、绑定、用户、权限和虚拟主机的所有元数据定义存储在内存中。优点是可以更快地进行开关和队列声明等操作。集群元数据RabbitMQ内部有各种基本组件,包括队列、交换机、绑定、虚拟主机等,这些组件以元数据的形式存在:队列元数据:队列的名称和声明队列时设置的属性(是否ispersistent是否自动删除,队列所属的节点)Exchange元数据:交换机的名称、类型、属性(是否持久化等)Binding元数据:一个简单的表,显示如何将消息路由到队列。包含的列包括Exchange名称、Exchange类型、routing\_key、queue\_name等。vhost元数据:为vhost中的队列、交换机和绑定提供命名空间和安全属性。一般rabbitmq启动时默认是磁盘节点。1,普通普通模式模式rabbitmq01divabbitmq02disc在兔子在rabbitmq02上上进行进行进行,执行执行执行集群####rabbitmqctlstop_appstoppingrabbit应用程序xnklxnklxnklxnklxnkl@rabbitmq02...xnkl@rabbitmq02...完成了3个插件。#看rabbitmq02控制台,显示加入集群正常,然后在rabbitmq02上操作,添加exchange。可以看到在添加交换机的时候,并没有节点配置的选项。这是因为rabbitmq集群所有节点上exchange的元数据都是一样的,并没有说属于某个节点。然后添加一个队列,可以看到添加队列的时候可以选择一个节点配置。意思是指定这个队列的属主节点。然后在rabbitmq01的控制台查看,rabbitmq02上添加的exchange和queue可以同步到rabbitmq01上。通过PHP脚本发布消息(PHP脚本连接rabbitmq01节点),发现rabbitmq01和rabbitmq02都可以查看消息,然后在rabbitmq01上设置consumer取出消息并ack,发现两个节点的队列'queue02'没有消息。说明此时消息同步正常。为了测试,将5条消息发布到队列“queue02”中,所有这些消息都是持久消息。继续测试异常。因为'queue02'属于节点rabbitmq02,现在关闭rabbitmq02服务。当rabbitmq02服务异常时,可以在rabbitmq01的控制台看到'queue02'队列的状态为'down',无法正常查看队列详情。并通过控制台开关列表,查看队列的绑定关系,发现绑定暂时消失了。此时通过PHP脚本发布消息,发现无法正常投递(basic_publish),触发'return_listener'。以下是PHP脚本记录的日志内容。如果再次声明队列(queue_declare),会报错“NOT_FOUND-homenode'xnkl@rabbitmq02'ofdurablequeue'queue02'invhost'/'isdownorinaccessible”。如果设置消费者消费队列(basic_consume),会报错NOT_FOUND-nopreviouslydeclaredqueue2020-04-2317:15:03.579[ERROR]-[23]-[App\Utility\RabbitMQ\MQCommon.App\Utility\RabbitMQ\{closure}.(/www/mqs/App/Utility/RabbitMQ/MQCommon.php:323)]:MQS_MSG_PUBLISH_ERROR|消息未传送到目标队列|replyCode:312|replyText:NO_ROUTE|exchangeName:exchange02|routingKey:exchange02|logMark:|msg:createTime:1587633303usedCount:0当队列的owner节点服务失败时,其他节点无法操作队列(包括队列声明、队列消费、消息投递),而出现一些异常情况(包括队列状态为‘down’,队列的绑定会暂时消失),只能等待节点服务恢复正常,这是普通集群模式的不足之处。当rabbitmq02服务恢复正常后,在控制台面板观察情况,队列元数据、绑定元数据、队列消息都恢复正常。·····Rabbitmq02在上面的测试中是磁盘节点,现在换成内存节点再测试。在更改磁盘节点类型之前,需要先停止rabbitmq服务,否则会报错。执行以下命令:##rabbitmqctlchange_cluster_node_typeramError:此命令需要在目标节点上停止“rabbit”应用程序。使用“rabbitmqctlstop_app”停止它。给出的参数:change_cluster_node_typeramUsagerabbitmqctl[--node][longnames][--quiet]change_cluster_node_type#rabbitmqctlstop_appStoppingrabbitapplicationonnodexnkl@rabbitmq02...#rabbitmqctlchange_cluster_node_typeramTurningxnkl@rabbitmq02intoramnode#rabbitmqctlstart_appStartingnodexnkl@rabbitmq02...completedwith3plugins.#可以看到替换成功.但是更改节点类型后,发现刚才的队列消失了(当然队列中原来消失的也会消失)。估计更改节点类型会导致队列元数据被清除(猜测,未确认)。但是exchange还是存在的,但是可以观察到bindingmetadata也消失了。这个时候创建??一个queue,配置一个routingkey,然后执行上面的异常测试,停止rabbitmq02节点服务。发现情况和rabbitmq02为磁盘节点时一样(包括无法声明队列、消费队列、传递消息、队列状态为‘down’、队列的绑定会暂时消失)。这个可能和网上其他博文描述的有点不一样,就是如果队列的owner节点(不管是内存节点还是磁盘节点)crash了,队列的元数据和绑定元数据在节点不会丢失。下图摘自网上其他文章,大家可以参考一下,因为版本不同可能导致结果不同。因此,对于普通集群模式下的队列,如果某个节点服务宕机,则属于该节点的队列无法正常运行,只能等待节点服务恢复。2.镜像集群模式镜像集群模式是在普通集群模式的基础上实现高可用。就是把switch队列等做成一个镜像,存在于多个节点,属于rabbitmq的‘HA’策略方案。在添加策略之前,队列“queue02”中有5条消息。先添加一个简单的policy,pattern=^是匹配所有的交换机和队列,优先级可以不设置,ha-mode=all是针对集群中的所有节点。添加以上策略后,查看队列的特征可以看到应用的策略。但是也发现了一些红色的异常,说明rabbitmq01的镜像还没有同步,因为在添加policy之前队列中已经存在一些消息。'+1'表示当前集群只有2个节点,其中1个节点还没有同步。这时候如果rabbitmq02服务崩溃了,其实会出现一些不正常的情况。·queue02队列状态显示异常,但不像正常集群模式那样显示down。·basic_publish,会发现消息不能正常发布,会触发return_listener·queue_delcare,会报错“NOT_FOUND-failedtoperformoperationonqueue'queue02invhost'/'duetotimeout”·basic_consume,会报错“NOT_FOUND-nopreviouslydeclaredqueue”·发现在控制台无法执行'publishmessage'和'getmessage'。这种情况明显不正常,队列不能正常操作。一种解决方案是手动执行同步镜像,“rabbitmqctlsync_queuequeue02”。但是在同步队列镜像的时候,要保证rabbitmq02的服务是正常的,否则只会阻塞等待,然后超时就报错。同步命令执行后,控制台“红色”提示消失。如果之后继续发布消息,也可以正常完成同步。此时如果rabbitm02服务停止,队列'queue02'仍然可以正常工作,正常发布消息,正常消费消息等。这就是镜像集群模式比普通集群模式更好实现高可用的地方。消息实体会主动在镜像节点之间进行同步,而不是像普通模式那样在消费者消费数据时临时读取。缺点是集群内部同步通信会占用大量网络带宽。还有一种方式,就是在创建策略的时候设置更多的参数。一般来说,你不会只设置一个‘ha-mode’,但你通常会将它与这些参数一起设置,如下所示。这样在创建策略时,可以自动同步所有队列镜像,不会有红色异常提示。这样rabbitmq的镜像集群就配置好了。镜像集群也是生产应用的常用模式。使用普通集群模式应该很少见,毕竟缺点很明显。无论磁盘节点挂掉还是队列的属主节点挂掉,服务仍然可以正常访问。Rabbitmq集群数据同步,出于存储空间和性能的考虑,集群内只同步元数据。比如三个节点组成一个RabbitMQ集群,ExchangeA的元数据信息在所有节点上都是一致的,而Queue(存储消息的队列)的完整数据只会存在于它创建的节点上,其他节点只知道元数据队列的信息和指向队列所有者节点的指针。联邦有待学习铲子有待学习参考资料https://blog.51cto.com/111346...https://zhuanlan.zhihu.com/p/...https://geewu.gitbooks.io/rab。..http://chyufly.github.io/blog...最后写的是我在开发过程中遇到的一些问题。这绝不是官方的解释。有不对的地方还请大家指正和讨论,以互相学习进步为目标。