一、rabbitmq单机版安装
1.下载安装包和依赖包
erlang-18.3-1.el7.centos.x86_64.rpm
socat-1.7.3.2-1.1.el7.x86_64.rpm
rabbitmq-server-3.6.5-1.noarch.rpm
下载地址:https://download.csdn.net/download/eakom/13841244
2.安装tcp_wrappers依赖
yum -y install tcp_wrappers
3.上传到Linux的/usr/local/rabbitmq目录下并按顺序安装(先装erlang,再装socat、最后rabbitmq)
cd /usr/local/rabbitmq
rpm -ivh erlang-18.3-1.el7.centos.x86_64.rpm
rpm -ivh socat-1.7.3.2-1.1.el7.x86_64.rpm
rpm -ivh rabbitmq-server-3.6.5-1.noarch.rpm
4.启动插件
rabbitmq-plugins enable rabbitmq_management
5.启动rabbitmq
service rabbitmq-server start
6.rabbitmq启动使用浏览器可以打开管理插件(防火墙开放15672端口)
访问地址:http://ip:15672/
二、rabbitmq配置
默认情况下,访问RabbitMQ服务的用户名和密码都是 guest",这个账户有限制,默认只能通过本地网络(如localhost )访问,远程网络访问受限,所以在实现生产和消费消息之前,需要另外添加一个用户,并设置相应的访问权限。
1.用户与权限介绍
//设置用户为管理员(没有管理员权限不可以登录)
rabbitmqctl add_user admin E@2020
//为用户赋权(没有配置权限只允许登录,没有其他权限)
rabbitmqctl set_user_tags admin administrator
//使用户add具有所有资源的配置、写、读权限以便管理其中的资源
rabbitmqctl set_permissions -p / admin '.*' '.*' '.*'
//查看用户列表
rabbitmqctl list_users
// 查看权限
rabbitmqctl list_user_permissions user1
rabbitmqctl list_permissions -p vhost1
// 清除权限
rabbitmqctl clear_permissions [-p VHostPath] User
//删除用户
rabbitmqctl delete_user Username
//修改用户的密码
rabbitmqctl change_password Username Newpassword
//设置权限并制定虚拟机
rabbitmqctl set_permissions -p vhost1 user1 '.*' '.*' '.*'
2.配置
例:创建一个超级用户
rabbitmqctl add_user admin1 admin1
rabbitmqctl set_user_tags admin1 administrator
//查看用户列表
rabbitmqctl list_users
//为用户赋权,使用户user1具有vhost1这个virtual host中所有资源的配置、写、读权限以便管理其中的资源
rabbitmqctl set_permissions -p vhost1 user1 '.*' '.*' '.*'
// 查看权限
rabbitmqctl list_user_permissions user1
rabbitmqctl list_permissions -p vhost1
// 清除权限
rabbitmqctl clear_permissions [-p VHostPath] User
// 删除用户
rabbitmqctl delete_user Username
// 修改用户的密码
rabbitmqctl change_password Username Newpassword
单机模式安装完成。
三、普通集群模式配置:3台服务器分别是node1、node2和node3 ,其对应IP如下:
node1对应IP:192.168.158.11
node2对应IP:192.168.158.12
node2对应IP:192.168.158.12
1.分别在三台服务器安装了rabbitmq,把node1的COOKIE值复制到node2和node3服务器,COOKIE的路径/var/lib/rabbitmq/.erlang.COOKIE
scp /var/lib/rabbitmq/.erlang.COOKIE node2:/var/lib/rabbitmq
scp /var/lib/rabbitmq/.erlang.COOKIE node3:/var/lib/rabbitmq
2.启动3台服务器systemctl start rabbitmq-server.service
查看集群状态rabbitmqctl cluster_status
3.关闭node2和node3应用rabbitmqctl stop_app
4.分别在node2服务器、node3服务器上把node2、node3作为内存节点与node1磁盘节点连接起来。rabbitmqctl join_cluster --ram rabbit@node1
3.启动node2和node3应用rabbitmqctl start_app
4.分别查看3台rabbitmq服务器的状态
普通集群模式配置完成。
四、镜像模式集群配置:
1、首先查看策略
rabbitmqctl list_policies
2、镜像队列策略
用法:
set_policy [-p vhost] [--priority priority] [--apply-to apply-to] {name} {pattern} {definition}Sets a policy.priorityThe priority of the policy as an integer. Higher numbers indicate greater precedence. The default is 0.nameThe name of the policy.patternThe regular expression, which when matches on a given resources causes the policy to apply.definitionThe definition of the policy, as a JSON term. In most shells you are very likely to need to quote this.apply-toWhich types of object this policy should apply to - "queues", "exchanges" or "all". The default is "all".For example:rabbitmqctl set_policy federate-me "^amq." '{"federation-upstream-set":"all"}'This command sets the policy federate-me in the default virtual host so that built-in exchanges are federated.
释义:
-p Vhost: 可选参数,针对指定vhost下的queue进行设置
Name: policy的名称,可以自定义
Pattern: queue的匹配模式(正则表达式)
Definition: 镜像定义,包括三个部分ha-mode, ha-params, ha-sync-modeha-mode: 指明镜像队列的模式,有效值为 all/exactly/nodesall: 表示在集群中所有的节点上进行镜像exactly: 表示在指定个数的节点上进行镜像,节点的个数由ha-params指定nodes: 表示在指定的节点上进行镜像,节点名称通过ha-params指定ha-params: ha-mode模式需要用到的参数ha-sync-mode: 进行队列中消息的同步方式,有效值为automatic和manual,如果是自动做镜像回复,则该队列会处于不可用状态直到同步完成
priority: 可选参数,policy的优先级
ha-promote-on-shutdown: 用来控制选主的行为的,有效值为when-synced,always
详细案例例:
rabbitmqctl set_policy [ha-all] "^" '{"ha-mode":"all"}' //策略正则表达式为 “^” 表示所有匹配所有队列名称
rabbitmqctl set_policy -p [虚拟主机名称] [策略名称如ha-all ] "^" '{"ha-mode":"all" , "ha-sync-mode":"automatic"}'
将所有队列设置为镜像队列,即队列会被复制到各个节点,各个节点状态保持一致。
3、开始设置:在任意一个节点上执行:
rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all" , "ha-sync-mode":"automatic"}'
或者指定vhost:
rabbitmqctl set_policy -p demo ha-all "^" '{"ha-mode":"all" , "ha-sync-mode":"automatic"}'
五、配置高可用
采用HAProxy+Keepalived 方式来部署实现。
1.Haproxy负载代理
Haproxy安装在node1和node2节点上安装haproxy,安装教程参考:https://blog.csdn.net/eakom/article/details/111773568
3.修改配置文件:vi /etc/haproxy/haproxy.cfg 之后添加:
listen rabbitmq_local_cluster 0.0.0.0:5672 #配置TCP模式 mode tcpoption tcplog #简单的轮询 balance roundrobin #rabbitmq集群节点配置 server rabbit1 192.168.158.11:5672 check inter 5000 rise 2 fall 2 server rabbit2 192.168.158.12:5672 check inter 5000 rise 2 fall 2 server rabbit3 192.168.158.13:5672 check inter 5000 rise 2 fall 2
3.重启Haproxy
4.Keepalived安装
利用keepalived做主备,避免单点问题,实现高可用,在192.168.158.11和192.168.158.12节点上安装最新版keepalived,安装流程参考:keepalived安装
5.配置:keepalived
192.168.158.11(主)修改keepalived.conf为:Primary配置:
vrrp_script chk_haproxy {script "pidof haproxy"interval 2
}
vrrp_instance VI_1 {interface ens192state MASTERpriority 200virtual_router_id 10unicast_src_ip 192.168.158.11unicast_peer {192.168.158.12}authentication {auth_type PASSauth_pass password}virtual_ipaddress {192.168.158.10 //虚拟ip,对外提供服务}track_script {chk_haproxy}notify_master /loadbtify_master.sh
}
192.168.158.12(备)修改keepalived.conf为:Secondary配置:
vrrp_script chk_haproxy {script "pidof haproxy"interval 2
}
vrrp_instance VI_1 {interface ens192state BACKUPpriority 100virtual_router_id 10unicast_src_ip 192.168.158.12unicast_peer {192.168.158.11}authentication {auth_type PASSauth_pass password}virtual_ipaddress {192.168.1.10}track_script {chk_haproxy}notify_master /loadbtify_master.sh
}
启动keepalived即可,192.168.1.10是对外提供的统一地址。通过192.168.1.10:5672就可以访问rabbitmq服务。
六、集群常用命令
1、加入集群[–ram添加内存模式 默认disk模式]
rabbitmqctl join_cluster --ram rabbit@node1
2、查看集群状态
rabbitmqctl cluster_status
3、更改节点模式[顺序 关闭运用-〉更改类型->开启运用]
rabbitmqctl stop_app –停止运用服务
rabbitmqctl change_cluster_node_type disc/ram –更改节点为磁盘或内存节点
rabbitmqctl start_app –开启运用服务
4、创建策略(集群同步策略……)
set_policy [-p vhostpath] {name} {pattern} {definition} [priority]
5、查看策略
rabbitmqctl list_policies
6、移除远程offline的节点
6.1.节点2停掉应用
rabbitmqctl stop_app
6.2.节点1执行删除
rabbitmqctl forget_cluster_node rabbit@mq02
7、设置集群名称
rabbitmqctl set_cluster_name cluster_name
8、设置镜像模式
Rabbit提供镜像功能,需要基于rabbitmq策略来实现,政策是用来控制和修改群集范围的某个vhost队列行为和Exchange行为
set_policy [-p vhostpath] {name} {pattern} {definition} [priority]
rabbitmqctl set_policy ha-all “^ha.” “{”“ha-mode”":"“all”"}"
rabbitmqctl set_policy ha-all “^” “{”“ha-mode”":"“all”","“ha-sync-mode”":"“automatic”"}"
rabbitmqctl set_policy -p demo ha-all “^” “{”“ha-mode”":"“all”","“ha-sync-mode”":"“automatic”"}"
9、手动同步queue
rabbitmqctl sync_queue name
10、取消queue同步
rabbitmqctl cancel_sync_queue name
11、查看所有队列信息
rabbitmqctl list_queues
12、获取队列信息
rabbitmqctl list_queues[-p vhostpath] [queueinfoitem …]
Queueinfoitem可以为:name,durable,auto_delete,arguments,messages_ready,messages_unacknowledged,messages,consumers,memory。
13、获取Exchange信息
rabbitmqctl list_exchanges[-p vhostpath] [exchangeinfoitem …]
Exchangeinfoitem有:name,type,durable,auto_delete,internal,arguments。
14、获取Binding信息
rabbitmqctl list_bindings[-p vhostpath] [bindinginfoitem …]
Bindinginfoitem有:source_name,source_kind,destination_name,destination_kind,routing_key,arguments。
15、获取Connection信息
rabbitmqctl list_connections [connectioninfoitem …]
Connectioninfoitem有:recv_oct,recv_cnt,send_oct,send_cnt,send_pend等。
16、获取Channel信息
rabbitmqctl list_channels[channelinfoitem …]
Channelinfoitem有consumer_count,messages_unacknowledged,messages_uncommitted,acks_uncommitted,messages_unconfirmed,prefetch_count,client_flow_blocked。
七、rabbitmq中镜像队列注意点
RabbitMQ的mirror queue(镜像队列)机制是最简单的队列HA方案,它通过在cluster的基础上增加ha-mode、ha-param等policy选项,可以根据需求将cluster中的队列镜像到多个节点上,从而实现高可用,消除cluster模式中队列内容单点带来的风险。
在使用镜像队列之前,有几点注意事项:
1.镜像队列不能作为负载均衡使用,因为每个操作在所有节点都要做一遍。
2.ha-mode参数和durable declare对exclusive队列都不生效,因为exclusive队列是连接独占的,当连接断开,队列自动删除。所以实际上这两个参数对exclusive队列没有意义。
3.将新节点加入已存在的镜像队列时,默认情况下ha-sync-mode=manual,镜像队列中的消息不会主动同步到新节点,除非显式调用同步命令。当调用同步命令(via rabbitmqctl or web-based ui)后,队列开始阻塞,无法对其进行操作,直到同步完毕。当ha-sync-mode=automatic时,新加入节点时会默认同步已知的镜像队列。由于同步过程的限制,所以不建议在生产环境的active队列(有生产消费消息)中操作。
4.每当一个节点加入或者重新加入(例如从网络分区中恢复回来)镜像队列,之前保存的队列内容会被清空。
5.镜像队列有主从之分,一个主节点(master),0个或多个从节点(slave)。当master宕掉后,会在slave中选举新的master。选举算法为最早启动的节点。
6.当所有slave都处在(与master)未同步状态时,并且ha-promote-on-shutdown policy设置为when-syned(默认)时,如果master因为主动的原因停掉,比如是通过rabbitmqctl stop命令停止或者优雅关闭OS,那么slave不会接管master,也就是说此时镜像队列不可用;但是如果master因为被动原因停掉,比如VM或者OS crash了,那么slave会接管master。这个配置项隐含的价值取向是优先保证消息可靠不丢失,放弃可用性。如果ha-promote-on-shutdown policy设置为alway,那么不论master因为何种原因停止,slave都会接管master,优先保证可用性。
7.镜像队列中最后一个停止的节点会是master,启动顺序必须是master先起,如果slave先起,它会有30秒的等待时间,等待master启动,然后加入cluster。当所有节点因故(断电等)同时离线时,每个节点都认为自己不是最后一个停止的节点。要恢复镜像队列,可以尝试在30秒之内同时启动所有节点。
8.对于镜像队列,客户端basic.publish操作会同步到所有节点;而其他操作则是通过master中转,再由master将操作作用于salve。比如一个basic.get操作,假如客户端与slave建立了TCP连接,首先是slave将basic.get请求发送至master,由master备好数据,返回至slave,投递给消费者。
9.由8可知,当slave宕掉时,除了与slave相连的客户端连接全部断开之外,没有其他影响。当master宕掉时,会有以下连锁反应: 1)与master相连的客户端连接全部断开。 2)选举最老的slave为master。若此时所有slave处于未同步状态,则未同步部分消息丢失。 3)新的master节点requeue所有unack消息,因为这个新节点无法区分这些unack消息是否已经到达客户端,亦或是ack消息丢失在到老master的通路上,亦或是丢在老master组播ack消息到所有slave的通路上。所以处于消息可靠性的考虑,requeue所有unack的消息。此时客户端可能受到重复消息。 4)如果客户端连着slave,并且basic.consume消息时指定了x-cancel-on-ha-failover参数,那么客户端会收到一个Consumer Cancellation Notification通知,Java SDK中会回调Consumer接口的handleCancel()方法,故需覆盖此方法。如果不指定x-cancel-on-ha-failover参数,那么消费者就无法感知master宕机,会一直等待下去。 上面列出的注意事项整理自官方的HA文档。
八、rabbitmq中镜像队列的故障恢复
前提:两个节点(A和B)组成一个镜像队列。
1.场景1:A先停,B后停。 该场景下B是master(disk,A是ram),只要先启动B,再启动A即可。或者先启动A,再在30秒之内启动B即可恢复镜像队列。
2.场景2: A, B同时停。 该场景可能是由掉电等原因造成,只需在30秒之内连续启动A和B即可恢复镜像队列。
3.场景3:A先停,B后停,且A无法恢复。 该场景是场景1的加强版,因为B是master,所以等B起来后,在B节点上调用rabbitmqctl forget_cluster_node A,解除与A的cluster关系,再将新的slave节点加入B即可重新恢复镜像队列。
4.场景4:A先停,B后停,且B无法恢复。 该场景是场景3的加强版,比较难处理,早在3.1.x时代之前貌似都没什么好的解决方法,但是现在已经有解决方法了,在3.4.2版本亲测有效(我们当前使用的是3.3.5)。因为B是master,所以直接启动A是不行的,当A无法启动时,也就没办法在A节点上调用rabbitmqctl forget_cluster_node B了。新版本中,forget_cluster_node支持–offline参数,offline参数允许rabbitmqctl在离线节点上执行forget_cluster_node命令,迫使RabbitMQ在未启动的slave节点中选择一个作为master。当在A节点执行rabbitmqctl forget_cluster_node –offline B时,RabbitMQ会mock一个节点代表A,执行forget_cluster_node命令将B剔出cluster,然后A就能正常启动了。最后将新的slave节点加入A即可重新恢复镜像队列。
5.场景5: A先停,B后停,且A、B均无法恢复,但是能得到A或B的磁盘文件。 该场景是场景4的加强版,更加难处理。将A或B的数据库文件(默认在$RABBIT_HOME/var/lib目录中)拷贝至新节点C的目录下,再将C的hostname改成A或B的hostname。如果拷过来的是A节点磁盘文件,按场景4处理方式;如果拷过来的是B节点磁盘文件,按场景3处理方式。最后将新的slave节点加入C即可重新恢复镜像队列。
6.场景6:A先停,B后停,且A、B均无法恢复,且无法得到A或B的磁盘文件。 洗洗睡吧,该场景下已无法恢复A、B队列中的内容了。
参考:https://www.cnblogs.com/huligong1234/p/13549450.html#%E5%9B%9B%E3%80%81%E9%85%8D%E7%BD%AE%E9%AB%98%E5%8F%AF%E7%94%A8