Rabbitmq 集群高可用部署详细 (镜像模式)

本贴最后更新于 2263 天前,其中的信息可能已经事过境迁

序言

为什么搭建 rabbitmq 集群?rabbitmq 集群有那些模式?如何搭建 Rabbitmq 集群?rabbitmq 镜像高可用策略有那些?

  1. 首先这款产品本身的优点众多,大家最看好的便是他的异步化提高系统抗峰值能力,然后便是系统及功能结构解耦,那么照此两点来说,他的在整个系统中的作用还是至关重要的,那么如此重要,当然要考虑他的高可用性,那么便有啦第一个问题的解答。

  2. rabbitmq 有 3 种模式,但集群模式是 2 种。详细如下:

  • 单一模式:即单机情况不做集群,就单独运行一个 rabbitmq 而已。
  • 普通模式:默认模式,以两个节点(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 方案。该模式解决了普通模式中的问题,其实质和普通模式不同之处在于,消息实体会主动在镜像节点间同步,而不是在客户端取数据时临时拉取。该模式带来的副作用也很明显,除了降低系统性能外,如果镜像队列数量过多,加之大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗掉。所以在对可靠性要求较高的场合中适用。

环境准备

3台centos7.4操作系统,ip分别为:

192.168.31.154
192.168.31.155
192.168.31.156

修改 hosts 文件(3 台)

vim /etc/hosts
192.168.31.154 rabbitmq1
192.168.31.155 rabbitmq2
192.168.31.156 rabbitmq3

保证 3 台能 ping 通

[root@rabbitmq1 ~]# ping 192.168.31.154
PING 192.168.31.154 (192.168.31.154) 56(84) bytes of data.
64 bytes from 192.168.31.154: icmp_seq=1 ttl=64 time=0.025 ms
64 bytes from 192.168.31.154: icmp_seq=2 ttl=64 time=0.043 ms
64 bytes from 192.168.31.154: icmp_seq=3 ttl=64 time=0.042 ms
^C
--- 192.168.31.154 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.025/0.036/0.043/0.010 ms
[root@rabbitmq1 ~]# ping 192.168.31.155
PING 192.168.31.155 (192.168.31.155) 56(84) bytes of data.
64 bytes from 192.168.31.155: icmp_seq=1 ttl=64 time=0.742 ms
64 bytes from 192.168.31.155: icmp_seq=2 ttl=64 time=0.343 ms
^C
--- 192.168.31.155 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.343/0.542/0.742/0.200 ms
[root@rabbitmq1 ~]# ping 192.168.31.156
PING 192.168.31.156 (192.168.31.156) 56(84) bytes of data.
64 bytes from 192.168.31.156: icmp_seq=1 ttl=64 time=1.15 ms
64 bytes from 192.168.31.156: icmp_seq=2 ttl=64 time=0.380 ms
^C
--- 192.168.31.156 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.380/0.768/1.157/0.389 ms
[root@rabbitmq1 ~]# 

好啦,环境到此就就能满足啦,接下来我们把 rabbitmq 装在 3 台机器上。

安装 rabbitmq 依赖 erlang 环境,所以我们要先安装 erlang 环境。

yum install erlang

安装 socat

yum install -y socat 

下载 rabbitmq

wget http://www.rabbitmq.com/releases/rabbitmq-server/v3.6.15/rabbitmq-server-3.6.15-1.el6.noarch.rpm

安装 rabbitmq

rpm -ivh rabbitmq-server-3.6.15-1.el6.noarch.rpm

rabbitmq 常用命令

service rabbitmq-server start    启动
service rabbitmq-server stop    停止
service rabbitmq-server restart   重启

账号配置

安装启动后其实还不能在其它机器访问,rabbitmq 默认的 guest 账号只能在本地机器访问, 如果想在其它机器访问必须配置其它账号

配置管理员账号:

可以创建管理员用户,负责整个MQ的运维
rabbitmqctl add_user admin adminpasspord
赋予其administrator角色
rabbitmqctl set_user_tags admin administrator
创建RabbitMQ监控用户,负责整个MQ的监控
rabbitmqctl add_user  user_monitoring  passwd_monitor  
rabbitmqctl set_user_tags user_monitoring monitoring
创建某个项目的专用用户,只能访问项目自己的virtual hosts
rabbitmqctl set_user_tags user_monitoring management
创建和赋角色完成后查看并确认
rabbitmqctl list_users  

启动 rabbitmq 内置 web 插件, 管理 rabbitmq 账号等信息

rabbitmq-plugins enable rabbitmq_management

访问 http://你的地址:15672/#/users
页面如下:
image

rabbitmq 用户权限 VirtualHost

像 mysql 有数据库的概念并且可以指定用户对库和表等操作的权限。那 RabbitMQ 呢?RabbitMQ 也有类似的权限管理。在 RabbitMQ 中可以虚拟消息服务器 VirtualHost,每个 VirtualHost 相当月一个相对独立的 RabbitMQ 服务器,每个 VirtualHost 之间是相互隔离的。exchange、queue、message 不能互通。
在 RabbitMQ 中无法通过 AMQP 创建 VirtualHost,可以通过以下命令来创建

rabbitmqctl add_vhost [vhostname]

通常在权限管理中主要包含三步:

新建用户

rabbitmqctl add_user superrd superrd

配置权限

set_permissions [-p <vhostpath>] <user> <conf> <write> <read>
rabbitmqctl  set_permissions -p /suanyun  admin '.*' '.*' '.*'  

其中, 的位置分别用正则表达式来匹配特定的资源,如:

'^(amq.gen.*|amq.default)$'

可以匹配 server 生成的和默认的 exchange,’^$’不匹配任何资源

  • exchange 和 queue 的 declare 与 delete 分别需要 exchange 和 queue 上的配置权限
  • exchange 的 bind 与 unbind 需要 exchange 的读写权限
  • queue 的 bind 与 unbind 需要 queue 写权限 exchange 的读权限 发消息(publish)需 exchange 的写权限
  • 获取或清除(get、consume、purge)消息需 queue 的读权限

示例:我们赋予 superrd 在“/”下面的全部资源的配置和读写权限。

rabbitmqctl set_permissions -p / superrd ".*" ".*" ".*"

注意”/”代表 virtual host 为“/”这个“/”和 linux 里的根目录是有区别的并不是 virtual host 为“/”可以访问所以的 virtual host,把这个“/”理解成字符串就行。

需要注意的是 RabbitMQ 会缓存每个 connection 或 channel 的权限验证结果、因此权限发生变化后需要重连才能生效。

查看权限

rabbitmqctl list_user_permissions admin
rabbitmqctl list_permissions -p /

配置角色

rabbitmqctl set_user_tags [user] [role]

RabbitMQ 中的角色分为如下五类:none、management、policymaker、monitoring、administrator

官方解释如下:

management 
User can access the management plugin 
policymaker 
User can access the management plugin and manage policies and parameters for the vhosts they have access to. 
monitoring 
User can access the management plugin and see all connections and channels as well as node-related information. 
administrator 
User can do everything monitoring can do, manage users, vhosts and permissions, close other user’s connections, and manage policies and parameters for all vhosts.

  • none
    不能访问 management plugin

  • management
    用户可以通过 AMQP 做的任何事外加:
    列出自己可以通过 AMQP 登入的 virtual hosts
    查看自己的 virtual hosts 中的 queues, exchanges 和 bindings
    查看和关闭自己的 channels 和 connections
    查看有关自己的 virtual hosts 的“全局”的统计信息,包含其他用户在这些 virtual hosts 中的活动。

  • policymaker
    management 可以做的任何事外加:
    查看、创建和删除自己的 virtual hosts 所属的 policies 和 parameters

  • monitoring
    management 可以做的任何事外加:
    列出所有 virtual hosts,包括他们不能登录的 virtual hosts
    查看其他用户的 connections 和 channels
    查看节点级别的数据如 clustering 和 memory 使用情况
    查看真正的关于所有 virtual hosts 的全局的统计信息

  • administrator
    policymaker 和 monitoring 可以做的任何事外加:
    创建和删除 virtual hosts
    查看、创建和删除 users
    查看创建和删除 permissions
    关闭其他用户的 connections

如下示例将 superrd 设置成 administrator 角色。

rabbitmqctl set_user_tags superrd administrator

搭建 rabbitmq 的一般模式集群

在上述的 3 台机器上安装 rabbitmq 完成之后,你可以看到你的机器中有如下 1 个文件。路径在 $HOME 中或者在/var/lib/rabbitmq 中,文件名称为.erlang.cookie,他是一个隐藏文件。那么这文件存储的内容是什么,是做什么用的呢?

这样说吧:RabbitMQ 的集群是依赖 erlang 集群,而 erlang 集群是通过这个 cookie 进行通信认证的,因此我们做集群的第一步就是干 cookie。怎么干?

  1. 必须使集群中也就是 F,G 这两台机器的.erlang.cookie 文件中 cookie 值一致,且权限为 owner 只读。
chmod 600 /var/lib/rabbitmq/.erlang.cookie
  1. 查看集群状态,我的是已经做好的。
[root@rabbitmq1 rabbitmq]#  rabbitmqctl status
Status of node rabbit@rabbitmq1
[{pid,17572},
 {running_applications,
     [{rabbitmq_management,"RabbitMQ Management Console","3.6.15"},
      {rabbitmq_web_dispatch,"RabbitMQ Web Dispatcher","3.6.15"},
      {rabbitmq_management_agent,"RabbitMQ Management Agent","3.6.15"},
      {rabbit,"RabbitMQ","3.6.15"},
      {amqp_client,"RabbitMQ AMQP Client","3.6.15"},
      {rabbit_common,
          "Modules shared by rabbitmq-server and rabbitmq-erlang-client",
          "3.6.15"},
      {recon,"Diagnostic tools for production use","2.3.2"},
      {os_mon,"CPO  CXC 138 46","2.2.14"},
      {cowboy,"Small, fast, modular HTTP server.","1.0.4"},
      {ranch,"Socket acceptor pool for TCP protocols.","1.3.2"},
      {ssl,"Erlang/OTP SSL application","5.3.3"},
      {public_key,"Public key infrastructure","0.21"},
      {cowlib,"Support library for manipulating Web protocols.","1.0.2"},
      {crypto,"CRYPTO version 2","3.2"},
      {inets,"INETS  CXC 138 49","5.9.8"},
      {mnesia,"MNESIA  CXC 138 12","4.11"},
      {compiler,"ERTS  CXC 138 10","4.9.4"},
      {xmerl,"XML parser","1.3.6"},
      {syntax_tools,"Syntax tools","1.6.13"},
      {asn1,"The Erlang ASN1 compiler version 2.0.4","2.0.4"},
      {sasl,"SASL  CXC 138 11","2.3.4"},
      {stdlib,"ERTS  CXC 138 10","1.19.4"},
      {kernel,"ERTS  CXC 138 10","2.16.4"}]},
 {os,{unix,linux}},
 {erlang_version,
     "Erlang R16B03-1 (erts-5.10.4) [source] [64-bit] [smp:2:2] [async-threads:64] [hipe] [kernel-poll:true]\n"},
 {memory,
     [{connection_readers,0},
      {connection_writers,0},
      {connection_channels,0},
      {connection_other,2800},
      {queue_procs,2800},
      {queue_slave_procs,0},
      {plugins,1471200},
      {other_proc,23282232},
      {metrics,142320},
      {mgmt_db,526352},
      {mnesia,84160},
      {other_ets,2372704},
      {binary,890656},
      {msg_index,40536},
      {code,27114499},
      {atom,992409},
      {other_system,22458876},
      {allocated_unused,9790936},
      {reserved_unallocated,2389504},
      {total,91561984}]},
 {alarms,[]},
 {listeners,[{clustering,25672,"::"},{amqp,5672,"::"},{http,15672,"::"}]},
 {vm_memory_calculation_strategy,rss},
 {vm_memory_high_watermark,0.4},
 {vm_memory_limit,1589890252},
 {disk_free_limit,50000000},
 {disk_free,33908043776},
 {file_descriptors,
     [{total_limit,204700},
      {total_used,2},
      {sockets_limit,184228},
      {sockets_used,0}]},
 {processes,[{limit,1048576},{used,330}]},
 {run_queue,0},
 {uptime,2934},
 {kernel,{net_ticktime,60}}]
[root@rabbitmq1 rabbitmq]# rabbitmqctl cluster_status
Cluster status of node rabbit@rabbitmq1
[{nodes,[{disc,[rabbit@rabbitmq1]},{ram,[rabbit@rabbitmq3,rabbit@rabbitmq2]}]},
 {running_nodes,[rabbit@rabbitmq3,rabbit@rabbitmq2,rabbit@rabbitmq1]},
 {cluster_name,<<"rabbit_cluster">>},
 {partitions,[]},
 {alarms,[{rabbit@rabbitmq3,[]},{rabbit@rabbitmq2,[]},{rabbit@rabbitmq1,[]}]}]
[root@rabbitmq1 rabbitmq]# 

  1. 停止当前机器中 rabbitmq 的服务
    在 rabbitmq2,rabbitmq3 分别执行
rabbitmqctl stop_app
rabbitmqctl join_cluster --ram rabbit@rabbitmq1
rabbitmqctl start_app
  1. 打开网页管理页面查看 nodes
    image

如此便可以啦,你可以做下测试,验证下我们序言中说的普通模式的说明,那必须是杠杠对的。

RabbitMQ 高可用性集群镜像

在我们使用 rabbitmq 作为消息服务时,在服务负载不是很大的情况下,一般我们只需要一个 rabbitmq 节点便能为我们提供服务,可这难免会发生单点故障,要解决这个问题,我们便需要配置 rabbitmq 的集群和镜像。

首先镜像模式要依赖 policy 模块,这个模块是做什么用的呢?

policy 中文来说是政策,策略的意思,那么他就是要设置,那些 Exchanges 或者 queue 的数据需要复制,同步,如何复制同步?对就是做这些的。

这里有点内容的,我先上例子慢慢说:

rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'

参数意思为:

ha-all:为策略名称。

^:为匹配符,只有一个 ^ 代表匹配所有,^zlh 为匹配名称为 zlh 的 exchanges 或者 queue。

ha-mode:为匹配类型,他分为 3 种模式:all-所有(所有的 queue),exctly-部分(需配置 ha-params 参数,此参数为 int 类型比如 3,众多集群中的随机 3 台机器),nodes-指定(需配置 ha-params 参数,此参数为数组类型比如["rabbit@rabbitmq1","rabbit@rabbitmq2",,"rabbit@rabbitmq3"]这样指定为 3 台机器。)

接下来就可以测试 rabbitmq 高可用性集群了。

Rabbitmq 集群高可用部署详细

rabbitmq 下载地址

RabbitMQ 消息队列-VirtualHost 与权限管理

RabbitMQ 安装详解

RabbitMQ 高可用性集群镜像实施方案

  • CentOS

    CentOS(Community Enterprise Operating System)是 Linux 发行版之一,它是来自于 Red Hat Enterprise Linux 依照开放源代码规定释出的源代码所编译而成。由于出自同样的源代码,因此有些要求高度稳定的服务器以 CentOS 替代商业版的 Red Hat Enterprise Linux 使用。两者的不同在于 CentOS 并不包含封闭源代码软件。

    238 引用 • 224 回帖
  • RabbitMQ

    RabbitMQ 是一个开源的 AMQP 实现,服务器端用 Erlang 语言编写,支持多种语言客户端,如:Python、Ruby、.NET、Java、C、PHP、ActionScript 等。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。

    49 引用 • 60 回帖 • 362 关注
  • 安装

    你若安好,便是晴天。

    132 引用 • 1184 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...