rabbitMQ镜像模式搭建

一、环境

 配置hosts解析

192.168.1.135 rabbit-master01
192.168.1.136 rabbit-master02
192.168.1.137 rabbit-master03

关闭防火墙或者配置相关端口

二、安装yum源及rabbitmq

在所有机器上

curl -s https://packagecloud.io/install/repositories/rabbitmq/erlang/script.rpm.sh | sudo bash
curl -s https://packagecloud.io/install/repositories/rabbitmq/rabbitmq-server/script.rpm.sh | sudo bash
yum install rabbitmq-server-3.8.14 #以3.8.14版本为例  
rabbitmq-plugins enable rabbitmq_management
systemctl start rabbitmq-server  #服务配置文件安装包中不包含,如需要修改相关配置则需要从Github下载,以当前版本为例:https://github.com/rabbitmq/rabbitmq-server/blob/v3.8.14/deps/rabbit/docs/rabbitmq.conf.example
systemctl enable rabbitmq-server

三、设置集群为镜像模式

1.rabbit-master01上

scp /var/lib/rabbitmq/.erlang.cookie root@192.168.1.136:/var/lib/rabbitmq/.erlang.cookie #将cookie文件拷贝到其他服务器上,该文件类似秘钥文件,通过该文件实现各节点相互认证
scp /var/lib/rabbitmq/.erlang.cookie root@192.168.1.137:/var/lib/rabbitmq/.erlang.cookie
rabbitmqctl cluster_status|grep 'Cluster name' #查看当前集群名称,稍后其他节点加入是需要使用

2.其他节点

chown rabbitmq:rabbitmq /var/lib/rabbitmq/.erlang.cookie #因为是root拷贝,所以属性发生了变化,需要还原
systemctl restart rabbitmq-server #重启使 cookie生效
rabbitmqctl stop_app #终止rabbitMQ服务,但Erlang服务保持运行,如果服务已经存在数据可以使用 rabbitmqctl reset清除 rabbitmqctl join_cluster rabbit@rabbit
-master01 #当前节点加入到该集群,集群名称根据上一步获取,默认类型为disk节点,可以通过 --ram参数设置为内存节点,也可以加入后修改,整个集群必须存在一个disk节点 rabbitmqctl start_app

任意一节点执行 rabbitmqctl set_policy ha
-all "^" '{"ha-mode":"all"}' # 设置所有节点开启自动同步 rabbitmqctl cluster_status #查看nodes相关属性,该节点是否存在

四、验证

1. 创建用户
rabbitmqctl add_user admin admin123
 
2.设置用户角色 #rabbit有固定几种角色,具体百度
rabbitmqctl set_user_tags admin administrator
 
3.设置用户权限
rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"

#在本机和其他机器执行,查看是否可以列出
4.rabbitmqctl list_users 

5.访问任意节点web服务,使用刚刚创建的admin用户登录,端口15672

五、相关命令

rabbitmqctl stop [{pid_file}]
# 表示stop 在RabbitMQ服务器上运行的一个Erlang 节点,可以指定某一个 *pid_file*,表示会等待这个指定的程序结束


rabbitmqctl shutdown
# 表示终止RabbitMQ 服务器上的Erlang进程,如果终止失败,会返回非零数字


rabbitmqctl stop_app
# 表示终止RabbitMQ的应用,但是Erlang节点还在运行。该命令典型的运行在一些需要RabbitMQ应用被停止的管理行为之前,例如 reset


rabbitmqctl start_app
# 表示启动RabbitMQ的应用。该命令典型的运行在一些需要RabbitMQ应用被停止的管理行为之后,例如 reset


rabbitmqctl wait {pid_file}
# 表示等待RabbitMQ应用启动。该命令会等待指定的pid file被创建,也就是启动的进程对应的pid保存在这个文件中,然后RabbitMQ应用在这个进程中启动。如果该进程终止,没有启动RabbitMQ应用,就会返回错误。
# 合适的pid file是有rabbitmq-server 脚本创建的,默认保存在 Mnesia 目录下,可以通过修改 RABBITMQ_PID_FILE 环境变量来修改
# 例如 rabbitmqctl wait /var/run/rabbitmq/pid


rabbitmqctl reset
# 表示设置RabbitMQ节点为原始状态。会从该节点所属的cluster中都删除,从管理数据库中删除所有数据,例如配置的用户和vhost,还会删除所有的持久消息。
# 要想reset和force_reset操作执行成功,RabbitMQ应用需要处于停止状态,即执行过 stop_app


rabbitmqctl force_reset
# 表示强制性地设置RabbitMQ节点为原始状态。它和reset的区别在于,可以忽略目前管理数据库的状态和cluster的配置,无条件的reset。
# 该方法的使用,应当用在当数据库或者cluster配置损坏的情况下作为最后的方法。


rabbitmqctl rotate_logs {suffix}
# 表示将日志文件的内容追加到新的日志文件中去,这个新的日志文件的文件名是原有的日志文件名加上命令中的 suffix,并且恢复日志到原来位置的新文件中。
# 注意:如果新文件原先不存在,那么会新建一个;如果suffix为空,那么不会发生日志转移,只是重新打开了一次日志文件而已。


rabbitmqctl hipe_compile {directory}
# 表示在指定的目录下执行HiPE编译和缓存结果文件 .beam-files
# 如果需要父目录会被创建。并且在编译之前,该目录下的所有 .beam-files会被自动删除。
# 使用预编译的文件,你应该设置 RABBITMQ_SERVER_CODE_PATH 环境变量为 hipe_compile 调用指定的目录。

普通集群管理命令
rabbitmqctl join_cluster {clusternode} [--ram]
# 表示结合到指定的集群,如果有参数 --ram 表示作为RAM节点结合到该集群中。
# 该命令指令本节结合到指定的集群中,在结合之前,该节点需要reset,所以在使用时,需要格外注意。为了成功运行本命令,必须要停止RabbitMQ应用,例如 stop_app
# 集群节点有两种类型: disc 和 RAM。disc类型,复制数据在RAM和disc上,在节点失效的情况下,提供了冗余保证,也能从一些全局事件中恢复,例如所有节点失效。RAM类型,只复制数据在RAM上,主要表现在伸缩性上,特别是在管理资源(例如:增加删除队列,交换器,或者绑定)上表现突出。
# 一个集群必须至少含有一个disc节点,当通常都多余一个。通过该命令时,默认是设置为disc节点,如果需创建RAM节点,需要指定参数 --ram
# 执行此命令之后,在该节点上启动的RabbitMQ应用,在该节点挂掉之后,会尝试连接节点所在集群中的其他节点。
# 为了离开集群,可以 reset 该节点,也可以使用命令 forget_cluster_node 远程删除节点


rabbitmqctl cluster_status
# 表示显示通过节点类型聚合在一起的集群中的所有节点,还有目前正在运行的节点


rabbitmqctl change_cluster_node_type {disc|ram}
# 表示改变集群节点的类型。该操作的正确执行,必定会停止该节点。并且在调整一个node为ram类型时,该节点不能为该集群的唯一node


rabbitmqctl forget_cluster_node [--offline]
# 表示远程移除一个集群节点。要删除的节点必须脱机,如果没有脱机,需要使用 --offline 参数。当使用 --offline 参数时,rabbitmqctl不会去连接节点,而是暂时变成节点,以便进行变更。这在节点不能正常启动时非常有用。在这种情况下,节点会成为集群元数据的规范来源(例如哪些队列存在)。因此如果可以的话,应该使用此命令在最新的节点上关闭。
# --offline 参数使节点从脱机节点上移除。使用场景主要是在所有节点脱机,且最后一个节点无法联机时,从而防止整个集群启动。在其他情况不应该使用,否则会导致不一致。
# 例如 rabbitmqctl -n hare@mcnulty forget_cluster_node  rabbit@stringer
# 上述命令将从节点 hare@mcnulty 中移除节点 rabbit@stringer


rabbitmqctl rename_cluster_node {oldnode1} {newnode1} [oldnode2] [newnode2...]
# 表示在本地数据库上修改集群节点名称。该命令让rabbitmqctl暂时成为一个节点来做出做变更。因此,本地的待修改的集群节点一定要完全停止,其他节点可以是online或者offline


rabbitmqctl update_cluster_nodes {clusternode}
# 表示指示已经集群的节点在唤醒时联系 {clusternode} 进行集群。这与 join_cluster 命令不同,因为它不加入任何集群,它是检查节点是否已经在具有 {clusternode} 的集群中。
# 该命令的需求,是在当一个节点offline时,修改了集群节点的情形下。例如:节点A和B聚群,节点A offline了,节点C和B集群,并且B节点离开了该集群,那么当节点A起来的时候,A会尝试连接B,但是由于B节点已经不在该集群中,所以会失败。
# 通过 update_cluster_nodes -n A C 将会解决上述问题。


rabbitmqctl force_boot
# 表示强制确保节点启动,即使该节点并不是最后down的。
# 一般情况下,当你同时shut down了RabbitMQ集群时,第一个重启的节点应该是最后一个down掉的,因为它可能已经看到了其他节点发生的事情。但是有时候这并不可能:例如当整个集群lose power,那么该集群的所有节点会认为他们不是最后一个关闭的。
# 如果最后down的节点永久的lost,那么应该优先使用 rabbitmqctl forget_cluster_node --offline ,因为这将确保在丢失节点上的镜像队列得到优先处理。


rabbitmqctl sync_queue [-p vhost] {queue}
# {queue} 表示待同步的队列名称
# 指引含有异步slaves的镜像队列去同步自身。当队列执行同步化时,其将会被锁定(指所有publishers发送出去的和consumers获取到的队列都会被锁定)。为了成功执行此命令,队列必须要被镜像。
# 注意,排除消息的异步队列将最终被同步化,此命令主要运用于未被排除完全消息的队列。


rabbitmqctl cancel_sync_queue [-p vhost] {queue}
# 指引一个正在同步的镜像队列停止此操作。


rabbitmqctl purge_queue [-p vhost] {queue}
# {queue} 表示待清空消息的队列名称
# 该命令表示清空队列(即删除队列中的所有消息)


rabbitmqctl set_cluster_name {name}
# 设置集群的名称。在连接中,集群的名称被声明在客户端上,被同盟和插件用来记录一个消息所在的位置。集群的名称默认来自于集群中第一个节点的主机名,但是可以被修改。

操作用户的管理命令
rabbitmqctl add_user {username} {password}
# {username} 表示用户名; {password}表示用户密码
# 该命令将创建一个 non-administrative 用户


rabbitmqctl delete_user {username}
# 表示删除一个用户,该命令将指示RabbitMQ broker去删除指定的用户


rabbitmqctl change_password {username} {newpassword}
# 表示修改指定的用户的密码


rabbitmqctl clear_password {username}
# 表示清除指定用户的密码
# 执行此操作后的用户,将不能用密码登录,但是可能通过已经配置的SASL EXTERNAL的方式登录。


rabbitmqctl authenticate_user {username} {password}
# 表示指引RabbitMQ broker认证该用户和密码


rabbitmqctl set_user_tags {username} {tag ...}
# 表示设置用户的角色,{tag}可以是零个,一个,或者是多个。并且已经存在的tag也将会被移除。
# rabbitmqctl set_user_tags tonyg administrator 该命令表示指示RabbitMQ broker确保用户tonyg为一个管理员角色。
# 上述命令在用户通过AMQP方式登录时,不会有任何影响;但是如果通过其他方式,例如管理插件方式登录时,就可以去管理用户、vhost 和权限。


rabbitmqctl list_users
# 表示列出所有用户名信息

 

访问控制命令
rabbitmqctl add_vhost {vhost}
# {vhost} 表示待创建的虚拟主机项的名称


rabbitmqctl delete_vhost {vhost}
# 表示删除一个vhost。删除一个vhost将会删除该vhost的所有exchange、queue、binding、用户权限、参数和策略。


rabbitmqctl list_vhosts {vhostinfoitem ...}
# 表示列出所有的vhost。其中 {vhostinfoitem} 表示要展示的vhost的字段信息,展示的结果将按照 {vhostinfoitem} 指定的字段顺序展示。这些字段包括: name(名称) 和 tracing (是否为此vhost启动跟踪)。
# 如果没有指定具体的字段项,那么将展示vhost的名称。


rabbitmqctl set_permissions [-p vhost] {user} {conf} {write} {read}
# 表示设置用户权限。 {vhost} 表示待授权用户访问的vhost名称,默认为 "/"; {user} 表示待授权反问特定vhost的用户名称; {conf}表示待授权用户的配置权限,是一个匹配资源名称的正则表达式; {write} 表示待授权用户的写权限,是一个匹配资源名称的正则表达式; {read}表示待授权用户的读权限,是一个资源名称的正则表达式。
# rabbitmqctl set_permissions -p myvhost tonyg "^tonyg-.*" ".*" ".*"
# 例如上面例子,表示授权给用户 "tonyg" 在vhost为 `myvhost` 下有资源名称以 "tonyg-" 开头的 配置权限;所有资源的写权限和读权限。


rabbitmqctl clear_permissions [-p vhost] {username}
# 表示设置用户拒绝访问指定指定的vhost,vhost默认值为 "/"


rabbitmqctl list_permissions [-p vhost]
# 表示列出具有权限访问指定vhost的所有用户、对vhost中的资源具有的操作权限。默认vhost为 "/"。
# 注意,空字符串表示没有任何权限。


rabbitmqctl list_user_permissions {username}
# 表示列出指定用户的权限vhost,和在该vhost上的资源可操作权限。

六、使用Nginx/haproxy+keepalived四层代理实现服务高可用

七 、集群恢复与故障转移

前提:比如两个节点A和B组成一个镜像队列

场景1

场景:A先停,B后停
方案:该场景下B是Master,只要先启动B,再启动A即可。或者先启动A,再30秒之内启动B即可恢复镜像队列

场景2

场景: A、B同时停机
方案:该场景可能是由于机房掉电等原因造成的,只需在30秒之内连续启动A和B即可恢复镜像

场景3

场景:A先停,B后停,且A无法恢复
方案:改场景是场景1的加强版,因为B是Master,所以等B起来以后,在B节点上调用控制台命令: rabbitmqctl forget_cluster_node  A解除与A的Cluster关系,再将新的Slave节点加入B即可重新恢复镜像队列

场景4

场景:A先停,B后停,且B无法恢复
方案:该场景是场景3的加强版,比较难处理,原因是因为Master节点无法恢复,早在3.1.x时代之前没有什么好的解决方案,但是现在已经有解决方案了,在3.4.2以后的版本。因为B是主节点,所以直接启动A是不行的,当A无法启动的时候,也就没办法在A节点上调用之前的rabbitmqctl forget_cluster_node B命令了。新版本中, forget_cluster_node支持-offline参数
这就意味着允许rabbitmqctl在理想节点上执行该命令,迫使RabbitMQ在未启动Slave节点中选择一个节点作为Master。当在A节点执行rabbitmqctl forget_cluster_node -offline B时,RabbitMQ会mock一个节点代表A,执行forget_cluster_node命令将B剔除cluster,然后A就可以正常启动了,最后将新的Slave节点加入A即可重新恢复镜像队列

场景5

场景:A先停、B后停,且A、B均无法恢复,但是能得到A或B的磁盘文件
方案:这种场景更加难处理,只能通过恢复数据的方式去尝试恢复,将A或B的数据库文件默认在$RABBIT_HOME/var/lib/目录中,把它拷贝到新节点的对应目录下,再将新节点的hostname改成A或B的hostname,如果是A节点(Slave)的磁盘文件,则按照场景4处理即可,如果是B节点(Master)的磁盘文件,则按照场景3处理,最后将新的Slave加入到新节点后完成恢复

场景6

场景∶A先停、B后停,且A、B均无法恢复,且得不到A或B的磁盘文件
方案:嗯,大家可以洗洗睡啦~

八、开启监控

#任意节点执行,不需要重启
rabbitmq-plugins enable rabbitmq_prometheus

访问http://IP:15692/metrics 

grafana模板参考:https://grafana.com/orgs/rabbitmq 

posted @ 2023-04-26 14:31  百衲本  阅读(278)  评论(0编辑  收藏  举报
cnblogs_post_body { color: black; font: 0.875em/1.5em "微软雅黑" , "PTSans" , "Arial" ,sans-serif; font-size: 15px; } cnblogs_post_body h1 { text-align:center; background: #333366; border-radius: 6px 6px 6px 6px; box-shadow: 0 0 0 1px #5F5A4B, 1px 1px 6px 1px rgba(10, 10, 0, 0.5); color: #FFFFFF; font-family: "微软雅黑" , "宋体" , "黑体" ,Arial; font-size: 23px; font-weight: bold; height: 25px; line-height: 25px; margin: 18px 0 !important; padding: 8px 0 5px 5px; text-shadow: 2px 2px 3px #222222; } cnblogs_post_body h2 { text-align:center; background: #006699; border-radius: 6px 6px 6px 6px; box-shadow: 0 0 0 1px #5F5A4B, 1px 1px 6px 1px rgba(10, 10, 0, 0.5); color: #FFFFFF; font-family: "微软雅黑" , "宋体" , "黑体" ,Arial; font-size: 20px; font-weight: bold; height: 25px; line-height: 25px; margin: 18px 0 !important; padding: 8px 0 5px 5px; text-shadow: 2px 2px 3px #222222; } cnblogs_post_body h3 { background: #2B6695; border-radius: 6px 6px 6px 6px; box-shadow: 0 0 0 1px #5F5A4B, 1px 1px 6px 1px rgba(10, 10, 0, 0.5); color: #FFFFFF; font-family: "微软雅黑" , "宋体" , "黑体" ,Arial; font-size: 18px; font-weight: bold; height: 25px; line-height: 25px; margin: 18px 0 !important; padding: 8px 0 5px 5px; text-shadow: 2px 2px 3px #222222; } 回到顶部 博客侧边栏 回到顶部 页首代码 回到顶部 页脚代码