RabbitMQ 集群部署

简介

安装

环境依赖

1
yum install erlang -y

安装服务

1
2
3
4
cd /usr/src/
wget http://www.rabbitmq.com/releases/rabbitmq-server/v3.6.4/rabbitmq-server-3.6.4-1.noarch.rpm

yum install rabbitmq-server-3.6.4-1.noarch.rpm -y

启动测试

1
2
3
4
#启动服务
service rabbitmq-server start
#查看服务状态
service rabbitmq-server status

配置管理

增加账号

1
2
3
4
#增加
rabbitmqctl add_user admin 'admin'
#角色分配
rabbitmqctl set_user_tags admin administrator

vhost

运行多个vhost,以便于适用不同的业务需要,这样做既可以满足权限配置的要求,避免不同业务之间队列、交换机的命名冲突问题,

1
2
3
#vhost 
rabbitmqctl add_vhost personas
rabbitmqctl set_permissions -p personas joy '.*' '.*' '.*'

管理界面

1
rabbitmq-plugins enable rabbitmq_management

集群部署

集群模式

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文件一致。

注意该文件默认是400权限,修改后需要还原回去400。

集群组建

首先保证所有节点都可以正常启动服务。

停止服务

在所有节点执行以下操作,停止服务

1
service rabbitmq-server stop

集群启动

1、所有节点执行以下操作,启动集群

1
rabbitmq-server -detached

-detached
Start the server process in the background. Note that this will cause the pid not to be written to the pid file.

For example, runs RabbitMQ AMQP server in the background:
rabbitmq-server -detached

该参数简单说就是后台启动,始终没理解和service rabbitmq-server sart的区别

2、修改统一hosts文件

1
2
3
4
192.168.1.233 r0
192.168.1.234 r1
192.168.1.232 r2
192.168.1.229 r3

3、同步.erlang.cookie文件
所有节点从r0机器分发 /var/lib/rabbitmq/.erlang.cookie

4、在其他节点服务器操作加入集群

1
2
3
4
5
6
7
8
//默认是磁盘节点,如果是内存节点的话,需要加--ram参数

rabbitmqctl stop_app
rabbitmqctl join_cluster --ram rabbit@r0
rabbitmqctl start_app
rabbitmqctl stop_app
rabbitmqctl join_cluster rabbit@r0
rabbitmqctl start_app

验证集群

1、节点加入集群,此处使用的主机名意义和hosts中一个意义。

2、加入集群后,检查集群状态

问题整理

  • 之前加入集群的时候总提示错误rror: unable to connect to node rabbit@test_229: nodedown

    原因:在集群的所有机器都需要先执行rabbitmq-server -detached

  • unable to connect to epmd (port 4369) on base_233: nxdomain (non-existing domain)

原因:未启用管理插件

1
rabbitmq-plugins enable rabbitmq_management

集群节点操作

节点恢复过程中把数据删掉很重要,恢复一单结点,再清数据
节点增加:

1
2
3
4
5
1. rabbitmq-server -detached   --- .erlang.cooike的权限,400 属主rabbitmq
2. rabbitmqctl stop_app
3. rabbitmqctl join_cluster --ram rabbit@rabbitmq1
4. rabbitmqctl start_app
5. rabbitmqctl cluster_status

节点删除

1
2
3
4
5
1.  rabbitmq-server -detached
以上为基础,正常运行的mq节点直接进行23两步;4可省略或更改为rabbitmqctl stop
2. rabbitmqctl stop_app
3. rabbitmqctl reset
4. rabbitmqctl start_app

硬删除:
直接删掉集群中的某个节点:

1
2
3
rabbitmqctl forget_cluster_node   node_name
```
由disc-->ram

1.节点删除 rabbitmq-server -detached —rabbitctl stop_app—- rabbitmqctl reset ((–2.清除原数据(暂时备份到其他地方)–rabbitmqctl join_cluster –ram rabbit@rabbitmq1 ———— rabbitmqctl start_app))
2.清除原数据(暂时备份到其他地方)
3.节点增加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
由disc-->ram
先恢复到单结点,重启,清数据
加集群


### 镜像队列

#### 配置参数
1、在管理界面配置
<img src="https://img.mknight.cn/medivh/1553134452790.png" />

* Virtual host: 可选参数,针对指定vhost下的queue进行设置
* Name: policy的名称
* Pattern: queue的匹配模式(正则表达式)
* Definition:镜像定义,包括三个部分ha-mode, ha-params, ha-sync-mode

* ha-mode:指明镜像队列的模式,有效值为 all/exactly/nodes
* all:表示在集群中所有的节点上进行镜像
* exactly:表示在指定个数的节点上进行镜像,节点的个数由ha-params指定
* nodes:表示在指定的节点上进行镜像,节点名称通过ha-params指定
* ha-params:ha-mode模式需要用到的参数
* ha-sync-mode:进行队列中消息的同步方式,有效值为automatic和manual
* priority:可选参数,policy的优先级

2、任意节点命令行配置

rabbitmqctl set_policy ha-all “^” ‘{“ha-mode”:”all”}’
1

// 命令行方式添加策略
// 策略名称为ha-allqueue,策略模式为 all 即复制到所有节点,包含新增节点,策略正则表达式为 “^” 表示所有匹配所有队列名称。
rabbitmqctl set_policy -p ha-allqueue”^” ‘{“ha-mode”:”all”}’

1
2
3
4
5
6
7
8
9
10
这时候就变成多个节点了。
<img src="https://img.mknight.cn/medivh/1553135352884.png" />


## 负载均衡
AProxy 是一个免费的负载均衡软件,可以运行于大部分主流的 Linux 操作系统上。

HAProxy 提供了 L4(TCP) 和 L7(HTTP) 两种负载均衡能力,具备丰富的功能。HAProxy 的社区非常活跃,版本更新快速(最新稳定版 1.7.22017/01/13 推出)。最关键的是,HAProxy 具备媲美商用负载均衡器的性能和稳定性。它当前不仅仅是免费负载均衡软件的首选,更几乎成为了唯一选择。

因为 RabbitMQ 本身不提供负载均衡,下面我们就搭建 HAProxy,用作 RabbitMQ 集群的负载均衡。

yum -y install haproxy
cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
vim /etc/haproxy/haproxy.cfg

1
haproxy配置文件

global
log 127.0.0.1 local0 info
log 127.0.0.1 local1 notice
daemon
maxconn 4096

defaults
log global
mode tcp
option tcplog
option dontlognull
retries 3
option abortonclose
maxconn 4096
timeout connect 5000ms
timeout client 3000ms
timeout server 3000ms
balance roundrobin

listen private_monitoring
bind 0.0.0.0:8100
mode http
option httplog
stats refresh 5s
stats uri /stats
stats realm Haproxy
stats auth admin:admin

listen rabbitmq_admin
bind 0.0.0.0:8102
server r0 r0:15672
server r3 r3:15672

listen rabbitmq_cluster
bind 0.0.0.0:8101
mode tcp
option tcplog
balance roundrobin
timeout client 3h
timeout server 3h
server r0 r0:5672 check inter 5000 rise 2 fall 3
server r3 r3:5672 check inter 5000 rise 2 fall 3

1
2

启动 haproxy

haproxy -f /etc/haproxy/haproxy.cfg
`
HAProxy 配置了三个地址:

实际程序访问的端口为8101

这样,haproxy就可以使用啦。

------ 本文结束 ------

版权声明

Medivh's Notes by Medivh is licensed under a Creative Commons BY-NC-ND 4.0 International License.
Medivh创作并维护的Medivh's Notes博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证
本文首发于Medivh 博客( http://www.mknight.cn ),版权所有,侵权必究。