1、环境准备
IP地址 主机名 192.168.56.20 conch01 192.168.56.21 conch02 192.168.56.22 conch03
2、安装 rabbitmq集群
1、之前我们已经在conch01上面安装了一台rabbitmq,下面我们只需要在另外两台安装即可
conch02、conch03
![]()
![]()
2、配置.erlang.cookie
RabbitMQ 的集群是依赖 erlang 集群,而 erlang 集群是通过这个 cookie 进行通信认证的,因此,三台机器的配置文件需要一致
我们将conch01的/var/lib/rabbitmq/.erlang.cookie文件拷贝到其他两台机器下
scp /var/lib/rabbitmq/.erlang.cookie root@conch02:/var/lib/rabbitmq/.erlang.cookie scp /var/lib/rabbitmq/.erlang.cookie root@conch03:/var/lib/rabbitmq/.erlang.cookie
3、启动RabbitMQ服务,顺带启动Erlang虚拟机和RabbitMQ应用服务,三台节点下执行
rabbitmq-server -detached
4、在节点2执行
# rabbitmqctl stop会将Erlang虚拟机关闭 rabbitmqctl stop_app 只关闭rabbitmq服务 rabbitmqctl stop_app rabbitmqctl reset rabbitmqctl join_cluster rabbit@conch01 # 只启动rabbitmq服务 rabbitmqctl start_app
出现问题:
[root@conch03 rabbitmq]# rabbitmqctl stop_app Stopping rabbit application on node rabbit@conch03 ... Error: unable to perform an operation on node 'rabbit@conch03'. Please see diagnostics information and suggestions below. Most common reasons for this are: * Target node is unreachable (e.g. due to hostname resolution, TCP connection or firewall issues) * CLI tool fails to authenticate with the server (e.g. due to CLI tool's Erlang cookie not matching that of the server) * Target node is not running In addition to the diagnostics info below: * See the CLI, clustering and networking guides on https://rabbitmq.com/documentation.html to learn more * Consult server logs on node rabbit@conch03 * If target node is configured to use long node names, don't forget to use --longnames with CLI tools DIAGNOSTICS =========== attempted to contact: [rabbit@conch03] rabbit@conch03: * connected to epmd (port 4369) on conch03 * epmd reports node 'rabbit' uses port 25672 for inter-node and CLI tool traffic * TCP connection succeeded but Erlang distribution failed * suggestion: check if the Erlang cookie identical for all server nodes and CLI tools * suggestion: check if all server nodes and CLI tools use consistent hostnames when addressing each other * suggestion: check if inter-node connections may be configured to use TLS. If so, all nodes and CLI tools must do that * suggestion: see the CLI, clustering and networking guides on https://rabbitmq.com/documentation.html to learn more Current node details: * node name: 'rabbitmqcli-3-rabbit@conch03' * effective user's home directory: /var/lib/rabbitmq * Erlang cookie hash: vRfqB6mBzPh2BfPPZife/A== [root@conch03 rabbitmq]#
原因:
RabbitMQ的erlang.cookie和用户的cookie冲突了,需要用rabbitmq的cookie去覆盖用户的cookie。
解决:
sudo cp /var/lib/rabbitmq/.erlang.cookie ~/.erlang.cookie
重启即可
5、在节点3执行
rabbitmqctl stop_app rabbitmqctl reset rabbitmqctl join_cluster rabbit@conch02 rabbitmqctl start_app
6、查看集群状态
rabbitmqctl cluster_status
[root@conch01 ~]# rabbitmqctl cluster_status Cluster status of node rabbit@conch01 ... Basics Cluster name: rabbit@conch01 Disk Nodes rabbit@conch01 rabbit@conch02 rabbit@conch03 Running Nodes rabbit@conch01 rabbit@conch02 rabbit@conch03 Versions rabbit@conch01: RabbitMQ 3.8.12 on Erlang 23.2.6 rabbit@conch02: RabbitMQ 3.8.12 on Erlang 23.2.6 rabbit@conch03: RabbitMQ 3.8.12 on Erlang 23.2.6 Maintenance status Node: rabbit@conch01, status: not under maintenance Node: rabbit@conch02, status: not under maintenance Node: rabbit@conch03, status: not under maintenance Alarms (none) Network Partitions (none) Listeners Node: rabbit@conch01, interface: [::], port: 15672, protocol: http, purpose: HTTP API Node: rabbit@conch01, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication Node: rabbit@conch01, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0 Node: rabbit@conch02, interface: [::], port: 15672, protocol: http, purpose: HTTP API Node: rabbit@conch02, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication Node: rabbit@conch02, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0 Node: rabbit@conch03, interface: [::], port: 15672, protocol: http, purpose: HTTP API Node: rabbit@conch03, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication Node: rabbit@conch03, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0 Feature flags Flag: drop_unroutable_metric, state: enabled Flag: empty_basic_get_metric, state: enabled Flag: implicit_default_bindings, state: enabled Flag: maintenance_mode_status, state: enabled Flag: quorum_queue, state: enabled Flag: user_limits, state: enabled Flag: virtual_host_metadata, state: enabled [root@conch01 ~]#
7、需要重新设置用户(随便一台机器执行即可)
# 创建账号 rabbitmqctl add_user admin 123456 # 设置用户角色 rabbitmqctl set_user_tags admin administrator # 设置用户权限 rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*"
之后在三个集群节点的任意一个可视化界面登录均可
8、解除集群节点,node2和node3分别执行
rabbitmqctl stop_app rabbitmqctl reset rabbitmqctl start_app rabbitmqctl cluster_status # 此项命令均在node1上执行 rabbitmqctl forget_cluster_node rabbit@对应节点的hostname 例如:rabbitmqctl forget_cluster_node rabbit@conch02
3、镜像队列
1、使用镜像的原因
如果RabbitMQ集群中只有一个Broker节点,那么该节点的失效将导致整体服务的临时性不可用,并且也可能会导致消息的丢失。可以将所有消息都设置为持久化,并且对应队列的durable属性也设置为true,但是这样仍然无法避免由于缓存导致的问题:因为消息在发送之后和被写入磁盘井执行刷盘动作之间存在一个短暂却会产生问题的时间窗。通过publisherconfirm机制能够确保客户端知道哪些消息己经存入磁盘,尽管如此,一般不希望遇到因单点故障导致的服务不可用。
引入镜像队列(Mirror Queue)的机制,可以将队列镜像到集群中的其他Broker节点之上,如果集群中的一个节点失效了,队列能自动地切换到镜像中的另一个节点上以保证服务的可用性。2、搭建步骤
- 启动三台集群节点
随便找一个节点添加policy,例如我们在conch01节点
![]()
在conch01上创建一个队列试试
可以发现出现了一个加1,表示有一个备份
那么一旦conch01出现宕机,那么备份节点conch02就可以用了,
我们将conch01节点停掉再看一下:发现重新在节点3上再次备份一下,保证数据不丢失。
4、实现高可用负载均衡
HAProxy.提供高可用性、负载均衡及基于TCPHTTP应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案,包括Twitter,Reddit,StackOverflow,GitHub.在内的多家知名互联网公司在使用。HAProxy实现了一种事件驱动、单一进程模型,此模型支持非常大的井发连接数。
5、Federation Exchange
1、使用原因
(broker北京),(broker深圳)彼此之间相距甚远,网络延迟是一个不得不面对的问题。有一个在北京的业务(Client北京)需要连接(broker北京),向其中的交换器exchangeA.发送消息,此时的网络延迟很小,(Client北京)可以迅速将消息发送至exchangeA.中,就算在开启了publisherconfirm.机制或者事务机制的情况下,也可以迅速收到确认信息。此时又有个在深圳的业务(Client深圳)需要向exchangeA发送消息,那么(Client深圳)(broker北京)之间有很大的网络延迟,(Client深圳)将发送消息至exchangeA会经历一定的延迟,尤其是在开启了publisherconfirm.机制或者事务机制的情况下,(Client深圳)会等待很长的延迟时间来接收(broker北京)的确认信息,进而必然造成这条发送线程的性能降低,甚至造成一定程度上的阻塞。
将业务(Client深圳)部署到北京的机房可以解决这个问题,但是如果(Client深圳)调用的另些服务都部署在深圳,那么又会引发新的时延问题,总不见得将所有业务全部部署在一个机房,那么容灾又何以实现?这里使用Federation插件就可以很好地解决这个问题.
2、搭建步骤
需要保证每台节点单独运行
在每台机器上开启federation相关插件
# 每台节点均需执行以下命令 rabbitmq-plugins enable rabbitmq_federation rabbitmq-plugins enable rabbitmq_federation_management
原理图
在下游节点(node2)配置上游节点(node1)
添加policy
成功
![]()
6、Federation Queue
1、使用原因
联邦队列可以在多个Broker节点(或者集群)之间为单个队列提供均衡负载的功能。一个联邦队列可以连接一个或者多个上游队列(upstream queue),并从这些上游队列中获取消息以满足本地消费者消费消息的需求。
添加上下游配置(同10.4)
添加policy
7、Shovel
1、简介
Federation具备的数据转发功能类似,Shovel够可靠、持续地从一个Broker中的队列(作为源端,即source)拉取数据并转发至另一个Broker中的交换器(作为目的端,即destination)。作为源端的队列和作为目的端的交换器可以同时位于同一个Broker,也可以位于不同的Broker上。Shovel可以翻译为"铲子",是一种比较形象的比喻,这个"铲子"可以将消息从一方"铲子"另一方。Shovel行为就像优秀的客户端应用程序能够负责连接源和目的地、负责消息的读写及负责连接失败问题的处理。
2、开启插件(需要的机器都开启)
rabbitmq-plugins enable rabbitmq_shovel rabbitmq-plugins enable rabbitmq_shovel_management
3、添加shevel源和目的地