MQ,Message queue,消息队列,就是指保存消息的一个容器,类似于数据库、缓存等,用来保存数据的,常用的MQ组件有activeMQ、rabbitMQ、rocketMQ、zeroMQ。
RabbitMQ是一款热门的一款消息中间件,有大量的企业在使用;
RabbitMQ 的 Cluster 集群模式一般分为两种,普通模式和镜像模式。
普通模式:默认的集群模式,以两个节点(rabbit01、rabbit02)为例来进行说明。对于 Queue 来说,消息实体只存在于其中一个节点 rabbit01(或者 rabbit02),rabbit01 和 rabbit02 两个节点仅有相同的元数据,即队列的结构。当消息进入 rabbit01 节点的 Queue 后,consumer 从 rabbit02 节点消费时,RabbitMQ 会临时在 rabbit01、rabbit02 间进行消息传输,把 A 中的消息实体取出并经过 B 发送给 consumer。所以 consumer 应尽量连接每一个节点,从中取消息。即对于同一个逻辑队列,要在多个节点建立物理 Queue。否则无论 consumer 连 rabbit01 或 rabbit02,出口总在 rabbit01,会产生瓶颈。当 rabbit01 节点故障后,rabbit02 节点无法取到 rabbit01 节点中还未消费的消息实体。如果做了消息持久化,那么得等 rabbit01 节点恢复,然后才可被消费;如果没有持久化的话,就会产生消息丢失的现象。
镜像模式:将需要消费的队列变为镜像队列,存在于多个节点,这样就可以实现 RabbitMQ 的 HA 高可用性。作用就是消息实体会主动在镜像节点之间实现同步,而不是像普通模式那样,在 consumer 消费数据时临时读取。缺点就是,集群内部的同步通讯会占用大量的网络带宽。
节点信息:
RAM node:内存节点将所有的队列、交换机、绑定、用户、权限和 vhost 的元数据定义存储在内存中,好处是可以使得像交换机和队列声明等操作更加的快速。
Disk node:将元数据存储在磁盘中,单节点系统只允许磁盘类型的节点,防止重启 RabbitMQ 的时候,丢失系统的配置信息。
RabbitMQ 要求在集群中至少有一个磁盘节点,所有其他节点可以是内存节点,当节点加入或者离开集群时,必须要将该变更通知到至少一个磁盘节点。如果集群中唯一的一个磁盘节点崩溃的话,集群仍然可以保持运行,但是无法进行其他操作(增删改查),直到节点恢复。
解决方案:设置两个磁盘节点,至少有一个是可用的,可以保存元数据的更改。
认证方式:
通过Erlang Cookie,相当于共享秘钥的概念,长度任意,只要所有节点都一致即可。rabbitmq server在启动的时候,erlang VM会自动创建一个随机的cookie文件。cookie文件的位置: /var/lib/rabbitmq/.erlang.cookie 或者/root/.erlang.cookie。我们的为保证cookie的完全一致,采用从一个节点copy的方式,实现各个节点的cookie文件一致。注意修改文件的权限:600
相关端口:
4369 (epmd), 25672 (Erlang distribution):Epmd 是 Erlang Port Mapper Daemon 的缩写,在 Erlang 集群中相当于 dns 的作用,绑定在4369端口上。
5672, 5671 (AMQP 0-9-1 without and with TLS):AMQP 是 Advanced Message Queuing Protocol 的缩写,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,专为面向消息的中间件设计。基于此协议的客户端与消息中间件之间可以传递消息,并不受客户端/中间件不同产品、不同的开发语言等条件的限制。Erlang 中的实现有 RabbitMQ 等。
15672 (if management plugin is enabled):通过 http://serverip:15672
访问 RabbitMQ 的 Web 管理界面,默认用户名密码都是 guest。(注意:RabbitMQ 3.0之前的版本默认端口是55672,下同)
环境准备:
1、两台Centos8服务器,修改hostname 分别为 mq1、mq2
2、添加host关系
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 mq1
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.11.25 mq1
192.168.11.17 mq2
安装依赖:
dnf install esl-erlang -y #安装esl-erlang
dnf install ncurses-devel openssl-devel unixODBC-devel gcc- c++
下载rabbitmq-server-3.9.1-1.el8.noarch.rpm包;下载地址:https://www.rabbitmq.com/install-rpm.html
rpm -ivh rabbitmq-server-3.9.1-1.el8.noarch.rpm
相关命令:
[root@mq1 ~]# rabbitmq-server -deched --后台启动服务
[root@mq1 ~]# rabbitmqctl start_app --启动服务
[root@mq1 ~]# rabbitmqctl stop_app --关闭服务
[root@mq1 ~]# rabbitmq-plugins enable rabbitmq_management --启动web管理插件
[root@mq1 ~]# rabbitmqctl add_user zlh zlh --添加用户,密码
[root@mq1 ~]# rabbitmqctl set_user_tags zlh administrator --设置zlh为administrator权限
如果你看到如下操作,即表明启动成功啦,并且web管理页面的插件也启动成功,如果下面的6为0,则需要启动web管理插件
[root@mq1 ~]# rabbitmq-server -deched #所有节点启动
[root@mq1 ~]# rabbitmq-plugins enable rabbitmq_management #所有节点启动
同步/var/lib/rabbitmq/.erlang.cookie文件;
把节点mq1上的 /var/lib/rabbitmq/.erlang.cookie分发到其它节点上;
加入集群(默认是磁盘节点,如果是内存节点需要添加 --ram参数);
[root@F rabbitmq]# rabbitmqctl stop_app
[root@F rabbitmq]# rabbitmqctl join_cluster rabbit@mq2 --ram
Clustering node rabbit@mq1 with rabbit@mq2
[root@F rabbitmq]# rabbitmqctl start_app
查看集群状态:
Cluster status of node rabbit@mq1 ...
Basics
Cluster name: rabbit@mq1
Disk Nodes
rabbit@mq2
RAM Nodes
rabbit@mq1
Running Nodes
rabbit@mq1
rabbit@mq2
Versions
rabbit@mq1: RabbitMQ 3.9.1 on Erlang 24.0.5
rabbit@mq2: RabbitMQ 3.9.1 on Erlang 24.0.5
Maintenance status
Node: rabbit@mq1, status: not under maintenance
Node: rabbit@mq2, status: not under maintenance
Alarms
(none)
Network Partitions
(none)
Listeners
Node: rabbit@mq1, interface: [::], port: 15672, protocol: http, purpose: HTTP API
Node: rabbit@mq1, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Node: rabbit@mq1, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
Node: rabbit@mq2, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Node: rabbit@mq2, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
Node: rabbit@mq2, interface: [::], port: 15672, protocol: http, purpose: HTTP API
Feature flags
Flag: drop_unroutable_metric, state: disabled
Flag: empty_basic_get_metric, state: disabled
Flag: implicit_default_bindings, state: enabled
Flag: maintenance_mode_status, state: enabled
Flag: quorum_queue, state: enabled
Flag: stream_queue, state: enabled
Flag: user_limits, state: enabled
Flag: virtual_host_metadata, state: enabled
创建用户:
rabbitmqctl add_user admin admin #账户密码都是admin
rabbitmqctl set_user_tags zlh administrator #设置admin账户权限为为administrator权限
访问web界面:http://192.168.11.25:15672/#/ 使用admin 账户登陆
问题汇总:
如果无法加入集群,需要检查下 (所有)节点的rabbitmq_management 管理插件是否启用;
RabbitMQ 镜像集群模式:
参考地址:https://www.rabbitmq.com/ha.html
[root@mq1 tools]# rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
Setting policy "ha-all" for pattern "^" to "{"ha-mode":"all"}" with priority "0" for vhost "/" ...
参数意思为:
ha-all:为策略名称。
^:为匹配符,只有一个^代表匹配所有,^zlh为匹配名称为zlh的exchanges或者queue。
ha-mode:为匹配类型,他分为3种模式:all-所有(所有的queue),exctly-部分(需配置ha-params参数,此参数为int类型比如3,众多集群中的随机3台机器),nodes-指定(需配置ha-params参数,此参数为数组类型比如["3rabbit@mq1","rabbit@Gmq2"]这样指定为F与G这2台机器。)。
参考示例如下
web界面配置管理:
配置完看队列如下,其中表示ha-haall的说明用我的ha-haall策略啦,属于镜像模式,没有表示的就是普通模式:
Rabbit集群负载均衡:
HAProxy 提供高可用性、负载均衡以及基于 TCP 和 HTTP 应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。
安装haproxy:
yum install haproxy #安装haproxy
编辑haproxy.cfg
添加配置:
listen rabbitmq_cluster 0.0.0.0:5670
#配置TCP模式
mode tcp
#加权轮询
balance roundrobin
#RabbitMQ集群节点配置
server rabbitmq-1 192.168.11.25:5672 check inter 2000 rise 2 fall 3
server rabbitmq-2 192.168.11.17:5672 check inter 2000 rise 2 fall 3
启动haproxy
systemctl restart haproxy