RabbitMQ集群

2021年6月19日11:24:50 发表评论
摘要

【心语】世界上其实根本没有感同深受这回事,针不刺到别人身上,他们就不知道有多痛。

Rabbitmq简介
MQ(消息列队),是种应用程序对应程序的通信方法,应用程序通过读写出入列队的消息(针对应用程序的数据),而无需专用链接来连接它们,消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术,排队指的是应用程序通过列队来通信,队列的使用除去了接收和发送应用程序同时执行的要求
RabbitMQ是目前流行的开源的消息列队系统,用Erlang语言开发,Rabbitmq是AMQP(高级消息队列协议)的标准实现,支持多种客户端,如:python、ruby、.NET、java、JMS、C、PHP、Actionscript、xmpp、stomp、等支持AJAX。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然。它可以使对应的客户端(client)与对应的消息中间件(broker)进行交互。消息中间件从发布者(publisher)那里收到消息(发布消息的应用,也称为producer),然后将他们转发给消费者(consumers,处理消息的应用)。由于AMQP是一个网络协议,所以发布者、消费者以及消息中间件可以部署到不同的物理机器上面
消息列队的概念
消息列队即时信息的载体,为了让消息发送者和消息接收者都能够明白消息所承载的信息(消息发送者需要知道如何构造消息,消息接收者需要知道如何解析消息),它们就需要按照一种统一的格式描述消息,这种统一的格式称为消息协议,所以,有效的消息一定具有某一种格式而没有格式的消息是没有意义的
消息列队应用场景
消息列队在实际应用中常用的使用场景,异步处理,应用解耦,流量削峰和消息通讯四个场景
实验环境部署

系统

IP地址

主机名

用途

Centos 7.6

192.168.24.18

MQ1

磁盘节点

Centos 7.6

192.168.24.19

MQ2

磁盘节点

Centos 7.6

192.168.24.20

MQ3

内存节点

实现步骤:
1、修改主机hosts
[root@localhost ~]# vim /etc/hosts
192.168.24.18 MQ1
192.168.24.19 MQ2
192.168.24.20 MQ3
RabbitMQ集群
2、安装环境(我们是源码安装)
[root@localhost ~]# yum -y install wget gcc gcc-c++ kernel-devel m4 ncurses-devel make openssl-devel
3、下载安装 erlang 软件包
[root@localhost ~]# wget -c http://erlang.org/download/otp_src_18.2.1.tar.gz
[root@localhost ~]# tar xf otp_src_18.2.1.tar.gz
[root@localhost ~]# cd otp_src_18.2.1
[root@localhost ~]# ./configure --prefix=/usr/local/erlang
[root@localhost ~]#make && make install
[root@localhost otp_src_18.2.1]# echo "export PATH=\$PATH:/usr/local/erlang/bin" >> /etc/profile
4、下载安装rabbitMQ包并安装
[root@localhost ~]# wget -c http://mirrors.rootpei.com/rabbitmq/rabbitmq-server-generic-unix-3.6.9.tar.xz
[root@localhost ~]# tar xf rabbitmq-server-generic-unix-3.6.9.tar.xz
[root@localhost ~]# mv rabbitmq_server-3.6.9/ /usr/local/rabbitmq
[root@localhost ~]# echo "export PATH=\$PATH:/usr/local/rabbitmq/sbin" >> /etc/profile
[root@localhost ~]# source /etc/profile
5、启用web管理后台插件
[root@MM-WIKI ~]# ln -s /usr/local/rabbitmq/sbin/* /usr/bin/
[root@localhost ~]# rabbitmq-plugins enable rabbitmq_management
[root@localhost sbin]# rabbitmq-server -detached
停止MQ
[root@MQ2 ~]# rabbitmqctl stop
RabbitMQ集群
查看进程
RabbitMQ集群
查看端口
[root@localhost ~]# netstat -lntp|grep 5672
RabbitMQ集群
说明:15672web管理端口,5672则是和生产者、消费者通信的端口 25672:集群通信端口
#配置环境变量
#erlang
export PATH=$PATH:/usr/local/erlang/bin
#rabbitmq
export PATH=$PATH:/usr/local/rabbitmq/sbin
RabbitMQ集群
配置开启自启动
[root@MQ2 ~]# cd /lib/systemd/system
[root@MQ2 system]# vim rabbitmq.service

[Unit]
Description=rabitmq service
After=network.target
[Service]
Type=forking
User=root
Group=root
Environment="HOME=/usr/local/erlang/bin"
Environment="JAVA_HOME=/usr/local/java/jdk1.8.0_221"
ExecStart=/usr/local/rabbitmq/sbin/rabbitmq-server -detached
ExecReload=/usr/local/rabbitmq/sbin/rabbitmqctl stop
ExecStop=/usr/local/rabbitmq/sbin/rabbitmqctl stop
PrivateTmp=true
[Install]
WantedBy=multi-user.target

如下图:RabbitMQ集群
#添加开机自启
备注说明:如果启动报错,在下面有详解解决和说明
[root@MQ2 system]# systemctl enable rabbitmq
[root@MQ2 domains]# systemctl list-unit-files|grep rabbitmq #查看是否添加成功
RabbitMQ集群
5、创建MQ用户并添加为管理员
创建用户
[root@localhost ~]# rabbitmqctl add_user admin abc.123ASD
将用户加入到管理员组
[root@localhost ~]# rabbitmqctl set_user_tags admin administrator
给用户授权
[root@localhost ~]# rabbitmqctl set_permissions -p "/" admin "." "." ".*" RabbitMQ集群
登录成功!
RabbitMQ集群
说明:三台机子全部执行相同的操作,安装部署完毕即可

#集群模式详解(三种模式)
1、单一模式
即单机情况下不做集群,就单独运行一个rabbitmq而已
2、普通模式:默认模式的集群
1、master主节点上的所有数据都会同步到Slave从节点上,但是有一个意外,就是队列,master主节点上的队列不会同步到其他从节点上,尽管其他从节点可以看到和访问这个队列,实际上这个队列只存在于主节点中。因此,该集群也叫主从复制集群。【注意:从节点上还是有队列的结构,只是消息实体只存在于主节点master上】
2、当消息进入主节点master时,消费者可能监听的是从节点,从节点是没有消息实体的,rabbitmq会在主节点和从节点之间进行临时的消息传输,把主节点中的消息实体取出,经过从节点,发送给消费者。因此,consumer应尽量连接每一个节点,从中取消息
3、当主节点故障后,从节点无法取到主节点中还未消费的消息实体。如果做了消息持久化,那么等主节点恢复,然后才可被消费;如果没有持久化,就会产生消息丢失的现象。
4、核心解决的问题:当集群中某一时刻,master节点宕机,从节点能备份主节点的元数据信息【交换机,绑定关系,队列结构】等,但是没有存储消息实体。很鸡肋
3、镜像模式集群
把需要的队列做成镜像队列,存在与多个节点属于 RabbitMQ 的 HA 方案。该模式解决了普通模式中的问题,其实质和普通模式不同之处在于,消息实体会主动在镜像节点间同步,而不是在客户端取数据时临时拉取。该模式带来的副作用也很明显,除了降低系统性能外,如果镜像队列数量过多,加之大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗掉。所以在对可靠性要求较高的场合中适用
部署集群
Rabbitmq的集群是依赖于erlangde 集群工作的,所以必须先构建起erlang的集群环境中的各节点是通过一个magic cookie来实现的,这个cookie存放在/var/lib/rabbitmq/.erlang.cookie中,文件权限是400的权限。所以必须保证各节点cookie一致。否则节点之间就无法通信
什么是erlang.cookie文件
.erlang.cookie是erlang实现分布式的必要文件,erlang分布式的每一个节点上要保持相同的.erlang.cookie文件,同时该文件的权限为400。
.erlang.cookie文件路径,一般会存在于两个地方
第一个是:$HOME/.erlang.cookie;
第二个是:/var/lib/rabbitmq/.erlang.cookie
1、如果我们使用解压缩安装方式(二进制安装或者编译安装),那么该文件存在位置为$HOME目录下。即$HOME/.erlang.cookie。使用root安装,则位置为:/root/.erlang.cookie,其他用户为/home/用户名/.erlang.cookie。
2、如果我们使用rpm包方式安装,那么这个文件会存在于/var/lib/rabbitmq目录下
内存节点说明
将配置信息和元信息存储在内存中。性能是优于磁盘节点的。
RabbitMQ要求集群中至少有一个磁盘节点,当节点加入和离开集群时,必须通知磁盘节点(如果集群中唯一的磁盘节点崩溃了,则不能进行创建队列、创建交换器、创建绑定、添加用户、更改权限、添加和删除集群节点)。总之如果唯一磁盘的磁盘节点崩溃,集群是可以保持运行的,但不能更改任何东西。因此建议在集群中设置两个磁盘节点,只要一个可以,就能正常操作。
Disc: 磁盘节点,ram:内存节点,如下图是2台磁盘节点! RabbitMQ集群
#拷贝192.168.24.18的erlang.cookie的到其它两台服务器上
[root@MQ1 ~]#scp .erlang.cookie root@192.168.24.19:/root/.erlang.cookie
[root@MQ1 ~]#scp .erlang.cookie root@192.168.24.20:/root/.erlang.cookie
RabbitMQ集群
保持一致即可!
各节点全部重启rabbitmq并验证端口
[root@MQ2 ~]# rabbitmq-server –detached
[root@MQ1 ~]# rabbitmq-server –detached
[root@MQ3 ~]# rabbitmq-server –detached
RabbitMQ集群 4、查看各rabbitmq的服务集群状态
[root@MQ2 ~]# rabbitmqctl cluster_status
RabbitMQ集群
#停止应用程序
[root@MQ3 ~]# rabbitmqctl stop_app
RabbitMQ集群
#清空元数据
[root@MQ3 ~]# rabbitmqctl reset
RabbitMQ集群
#将MQ3添加到集群当中,并成为内存节点,不加—ram 默认就是磁盘节点
[root@MQ3 ~]# rabbitmqctl join_cluster rabbit@MQ2 --ram
RabbitMQ集群
# [root@MQ2 system]# rabbitmqctl cluster_statusRabbitMQ集群
验证数据是否正常,在任意一台MQ上输入命令查询
[root@MQ3 ~]# rabbitmqctl list_queues
RabbitMQ集群 在新的rabbitmq集群主节点踢出rabbit@controller7325节点,需要先停止在剔除
rabbitmqctl -n rabbit@controller7326 forget_cluster_node rabbit@controller7325
[root@MQ1 ~]# rabbitmqctl -n rabbit@MQ1 forget_cluster_node rabbit@MQ3
RabbitMQ集群
如:上图已清楚集群状态已经看不到 rabbit@MQ3
被剔除集群的服务器想重新加入集群操作如下
说明可以直接拷贝现有集群的软件包也可以直接重新解压安装包,我这里重新解压
[root@MQ2 data]# tar xf rabbitmq-server-generic-unix-3.6.9.tar.xz
[root@MQ2 data]# mv rabbitmq_server-3.6.9 /usr/local/rabbitmq
在到正常的MQ1服务器上同步4个文件
[root@MQ1 ~]# scp -r /usr/local/rabbitmq/sbin/.erlang.cookie root@192.168.24.19:/usr/local/rabbitmq/sbin/.erlang.cookie
scp -r /usr/local/erlang/bin/.erlang.cookie root@192.168.24.19:/usr/local/erlang/bin/.erlang.cookie
[root@MQ1 ~]# scp -r .erlang.cookie root@192.168.24.19:/root/.erlang.cookie
[root@MQ1 ~]# scp -r /usr/local/rabbitmq/etc/rabbitmq/rabbitmq-env.conf root@192.168.24.19:/usr/local/rabbitmq/etc/rabbitmq/RabbitMQ集群
说明:同步rabbitmq-env.conf这个文件需要修改下配置文件的主机名保持一致如下图
RabbitMQ集群
然后按照加入集群的步骤操作一遍:
[root@MQ2 rabbitmq]# rabbitmqctl cluster_status                #查看集群状态
[root@MQ2 rabbitmq]# rabbitmqctl stop_app                       #停止应用
[root@MQ2 rabbitmq]# rabbitmqctl reset                               #清除源数据
[root@MQ2 rabbitmq]# rabbitmqctl join_cluster rabbit@MQ1 –ram       #加入集群
[root@MQ2 rabbitmq]# rabbitmqctl start_app                                     #启动应用
[root@MQ2 rabbitmq]# rabbitmq-plugins enable rabbitmq_management clear       #开启web管理RabbitMQ集群
在使用上面的命令去添加用户等信息即可完成,如遇rabbitmq-server文件启动报错,第87几行读取不到erlang的环境变量,请看下面的操作方式解决即可
#集群Nginx负载均衡配置

#MQ集群代理
upstream mqcluster{
server 192.168.24.18:5672;
server 192.168.24.19:5672;
server 192.168.24.20:5672;
}
server {
listen 1234;
server_name 192.168.24.19;
location / {
#rewrite ^/rabbitmq/(.*)$ /$1 break;
proxy_pass http://mqcluster;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

RabbitMQ集群

#镜像集群
说明:如果不添加镜像集群模式,MQ的消息就无法在各个节点同步
rabbitmqctl set_policy ha1 '^hello' '{"ha-mode":"all","ha-sync-mode":"automatic"}' 
说明:ha1是策略名,^hello:匹配hello开头队列;  '^':表示对所有队列做镜像
#在添加rabbitmq系统服务使用systemctl start rabbitmq启动的报错解决
#配置rabbitmq开机自启服务,使用如下命令启动之后报错,查看集群状态报错
[root@MQ2 ~]# systemctl start rabbitmq #启动
[root@MQ2 ~]# rabbitmqctl cluster_status #查看状态和加入集群节点都报错如下
RabbitMQ集群
#解决办法
[root@MQ2 ~]# cd /usr/local/rabbitmq/etc/rabbitmq/
[root@MQ2 rabbitmq]# vim rabbitmq-env.conf
#加入如下代码

NODENAME=rabbit@MQ2
HOME=/usr/local/rabbitmq/sbin

RabbitMQ集群
保存退出,并重启服务
[root@MQ2 rabbitmq]# systemctl stop rabbitmq
[root@MQ2 rabbitmq]# systemctl start rabbitmq
#报错解决
在启动过程中,通过下面图中描述中,发现是rabbitmq-server文件第87没有找到erlang
RabbitMQ集群
#解决办法
在rabbitmq-server 87行附近添加
[root@MQ2 sbin]# vim rabbitmq-server
export PATH=$PATH:/usr/local/erlang/bin
RabbitMQ集群

  • 微信公众号
  • 这是我的微信公众号扫一扫
  • weinxin
  • 我的QQ技术群
  • 我的QQ技术群扫一扫
  • weinxin
admin

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: