RabbitMQ集群默认模式、使用Docker搭建RabbitMQ集群

七、RabbitMQ集群
1、默认模式
RabbitMQ集群允许消费者和生产者在RabbitMQ单个节点崩溃的情况下继续运行,它可以通过添加更多的节点来线性地扩展消息通信的吞吐量。当失去一个RabbitMQ节点时,客户端能够重新连接到集群中的任何其他节点并继续生产或者消费

RabbitMQ集群不能保证消息的万无一失,即使将消息、队列、交换机等都设置为可持久化,生产端和消费端都正确地使用了确认方式,当集群中一个RabbitMQ节点崩溃时,该节点上的所有队列中的消息也会丢失。RabbitMQ集群中的所有节点都会备份所有的元数据信息,包括以下内容:

队列元数据:队列的名称及属性
交换机:交换机的名称及属性
绑定关系元数据:交换机与队列或者交换机与交换机之间的绑定关系
vhost元数据:为vhost内的队列、交换机和绑定提供命名空间及安全属性
但是不会备份消息。基于存储空间和性能的考虑,在RabbitMQ集群中创建队列,集群只会在单个节点而不是在所有节点上创建队列的进程并包含完整的队列信息。这样只有队列的宿主节点,即所有者节点知道队列的所有信息,所有其他非所有者节点只知道队列的元数据和指向该队列存在的那个节点的指针。因此当集群节点崩溃时,该节点的队列进程和关联的绑定都会消失。附加在那些队列上的消费者也会丢失其所订阅的信息,并且任何匹配该队列绑定信息的新消息也都会消失

不同于队列那样拥有自己的进程,交换机其实只是一个名称和绑定列表。当消息发布到交换机时,实际上是由所连接的信道将消息上的路由键同交换机的绑定列表进行比较,然后再路由消息。当创建一个新的交换机时,RabbitMQ所要做的就是将绑定列表添加到集群中的所有节点上

2、使用Docker搭建RabbitMQ集群
1)、启动多个RabbitMQ

docker run -d --hostname rabbit1 --name myrabbit1 -p 15672:15672 -p 5672:5672 -e RABBITMQ_ERLANG_COOKIE='rabbitcookie' rabbitmq:3.6.15-management

docker run -d --hostname rabbit2 --name myrabbit2 -p 5673:5672 --link myrabbit1:rabbit1 -e RABBITMQ_ERLANG_COOKIE='rabbitcookie' rabbitmq:3.6.15-management

docker run -d --hostname rabbit3 --name myrabbit3 -p 5674:5672 --link myrabbit1:rabbit1 --link myrabbit2:rabbit2 -e RABBITMQ_ERLANG_COOKIE='rabbitcookie' rabbitmq:3.6.15-management

1)多个容器之间用--link连接

2)配置相同的Erlang Cookie

为什幺配置相同的Erlang Cookie?

因为RabbitMQ使用Erlang实现的,Erlang Cookie相当于不同节点之间相互通讯的秘钥,Erlang节点通过交换Erlang Cookie获得认证

Erlang Cookie的位置

首先要获取RabbitMQ启动日志里面的home dir路径,作为根路径。使用”docker logs 容器名称“查看

=INFO REPORT==== 3-May-2019::00:40:56 ===
node : rabbit@rabbit1
home dir : /var/lib/rabbitmq
config file(s) : /etc/rabbitmq/rabbitmq.config
cookie hash : l7FRc4s6MFrXQLBiUlLnOA==
log : tty
sasl log : tty
database dir : /var/lib/rabbitmq/mnesia/rabbit@rabbit1

所以Erlang Cookie的全部路径是“/var/lib/rabbitmq/.erlang.cookie”

root@rabbit1:/# cat /var/lib/rabbitmq/.erlang.cookie
rabbitcookie

复制Erlang Cookie到其他RabbitMQ节点

物理机和容器之间复制命令如下:

容器复制文件到物理机:docker cp 容器名称:容器目录 物理机目录
物理机复制文件到容器:docker cp 物理机目录 容器名称:容器目录
设置Erlang Cookie文件权限:“chmod 600 /var/lib/rabbitmq/.erlang.cookie”

2)、加入RabbitMQ节点到集群

rabbitmqctl join_cluster {cluster_node} [–ram]

将节点加入指定集群中。在这个命令执行前需要停止RabbitMQ应用并重置节点

参数--ram表示设置为内存节点,忽略此参数默认为磁盘节点

1)设置节点1

docker exec -it myrabbit1 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
exit

2)设置节点2

docker exec -it myrabbit2 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbit1
rabbitmqctl start_app
exit

3)设置节点3

docker exec -it myrabbit3 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbit1
rabbitmqctl start_app
exit
设置好之后访问http://IP:15672/,默认帐号密码是guest/guest

启动了3个节点,1个磁盘节点和2个内存节点

集群的节点类型

RabbitMQ中的每一个节点,不管是单一节点系统或者集群中的一部分,要么是内存节点,要么是磁盘节点。内存节点将所有的队列、交换机、绑定关系、用户、权限和vhost的元数据定义都存储在内存中,而磁盘节点则将这些信息存储到磁盘中。单节点的集群中必然只有磁盘类型的节点,否则当重启RabbitMQ之后,所有关于系统的配置信息都会丢失。不过在集群中,可以选择配置部分节点为内存节点,这样可以获得更高的性能

RabbitMQ只要求在集群中至少有一个磁盘节点,所有其他节点可以是内存节点。当节点加入或者离开集群时,它们必须将变更通知到至少一个磁盘节点。如果只有一个磁盘节点,而且刚好是它崩溃了,那么集群可以继续发送或者接收消息,但是不能执行创建队列、交换机、绑定关系、用户,以及更改权限、添加或者删除集群节点的操作了。也就是说,如果集群中唯一的磁盘节点崩溃,集群仍然可以保持运行,但是直到将该节点恢复到集群前,无法更改任何东西。所以在建立集群的时候应该保证有两个或者多个磁盘节点的存在

在内存节点重启后,它们会连接到预先配置的磁盘节点,下载当前集群元数据的副本。当在集群中添加内存节点时,确保告知其所有的磁盘节点。只要内存节点可以找到至少一个磁盘节点,那么它就能在重启后重新加入集群中

为了确保集群信息的可靠性,建议全部使用磁盘节点

3、SpringBoot整合RabbitMQ集群
和SpringBoot整合RabbitMQ主要是配置文件上存在差别:

spring.rabbitmq.addresses=192.168.126.151:5672,192.168.126.151:5673,192.168.126.151:5674
spring.rabbitmq.virtual-host=/
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

原文链接:https://blog.csdn.net/qq_40378034/article/details/89788708

原文地址:https://www.cnblogs.com/cheyunhua/p/15508088.html