RabbitMQ简介

用erlang语言开发。官网链接:http://www.rabbitmq.com/ (rabbitmq的特性、使用烦请百度)

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

    一个队列想做成镜像队列,需要先设置policy,然后客户端创建队列的时候,rabbitmq集群根据“队列名称”自动设置是普通集群模式或镜像队列。具体如下:
    队列通过策略来使能镜像。策略能在任何时刻改变,rabbitmq队列也近可能的将队列随着策略变化而变化;非镜像队列和镜像队列之间是有区别的,前者缺乏额外的镜像基础设施,没有任何slave,因此会运行得更快。为了使队列称为镜像队列,你将会创建一个策略来匹配队列,设置策略有两个键“ha-mode和 ha-params(可选)”。ha-params根据ha-mode设置不同的值,下面表格说明这些key的选项。

语法讲解:

在cluster中任意节点启用策略,策略会自动同步到集群节点

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

这行命令在vhost名称为hrsystem创建了一个策略,策略名称为ha-allqueue,策略模式为 all 即复制到所有节点,包含新增节点,策略正则表达式为 “^” 表示所有匹配所有队列名称。例如:

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

注意:“^message” 这个规则要根据自己修改,这个是指同步“message”开头的队列名称,我们配置时使用的应用于所有队列,所以表达式为“^”

RabbitMQ搭建前提

  1. 请确认有三台服务器(如果硬件不够,可以试用虚拟机);
  2. 熟悉常用Linux命令

第一步:Erlang下载

      下载地址:http://www.erlang.org/download.html ,我选择的版本是otp_src_20.0.tar.gz(下载erlang之前,需确定即将选择的rabbitmq版本及其对应的erlang版本,否则可能出现编译问题)。

      下载下来压缩包为otp_src_20.0.tar.gz。请使用tar -xvf otp_src_20.0.tar.gz解压至/opt目录

第二步:Erlang安装

  1. 安装依赖包:yum install gcc ncurses-devel openssl-devel unixODBC-devel
  2. 进入/opt/otp_src_20.0目录,依次执行以下命令:
    chmod a+x configure
    ./configure --prefix=/opt/erlang
    chmod a+x erts/autoconf/config.sub
    make && make install
    chmod a+x /opt/otp_src_20.0/make/install_bin
  3. 修改/etc/profile文件,增加下面的环境变量:
    ERL_HOME=/opt/erlang
    PATH=$ERL_HOME/bin:$PATH
    export ERL_HOME PATH
  4. source /etc/profile

第三步:RabbitMQ下载

      官网中找到对应版本安装包,执行以下命令下载对应rpm包文件至/opt目录:

      RPM包下载:wget http://www.rabbitmq.com/releases/rabbitmq-server/v3.6.12/rabbitmq-server-3.6.12-1.el6.noarch.rpm 

      TAR包下载:wget http://www.rabbitmq.com/releases/rabbitmq-server/v3.6.12/rabbitmq-server-generic-unix-3.6.12.tar.xz

第四步:RabbitMQ安装

  1. RPM包安装执行以下命令:
    chmod +x rabbitmq-server-3.6.12-1.el6.noarch.rpm
    yum install rabbitmq-server-3.6.12-1.el6.noarch.rpm
    TAR包安装执行以下命令:(我采用的是tar包安装方式)
    tar -xvf rabbitmq-server-generic-unix-3.6.12.tar.xz
  2. 启用RabbitMQWeb管理插件
    ./sbin/rabbitmq-plugins enable rabbitmq_management
  3. 启动服务
    ./sbin/rabbitmq-server -detached
  4. 查看服务状态
    ./sbin/rabbitmqctl status
  5. 关闭服务
    ./sbin/rabbitmqctl stop

    至此,RabbitMQ单一模式已安装完成

第五步:集群环境搭建

  1. 局域网配置 分别在三个节点的/etc/hosts下设置相同的配置信息
    红框中的IP地址与三台服务器的IP需要对应上,每台服务器都需要配置,node1、node2、node3名称可自行配置
    配置完成后,切记重启三台服务器。切记切记......
  2. 设置不同节点间同一认证的Erlang Cookie 采用从主节点copy的方式保持Cookie的一致性(x1位主节点)
    scp ~/.erlang.cookie root@10.100.xxx.x2:~
    scp ~/.erlang.cookie root@10.100.xxx.x3:~
    如果无法覆盖,需修改x2和x3的.erlang.cookie的读写权限:chmod 600 ~/.erlang.cookie
    拷贝完成后,检查每台服务器中的.erlang.cookie内容是否一致(很有必要)
    有些人安装完成erlang后,.erlang.cookie在/var/lib/rabbitmq/.erlang.cooki目录,如果找不到该文件,可全局搜索
  3. 使用 -detached运行各节点
    ./rabbitmqctl stop
    ./rabbitmq-server -detached 
  4. 查看各节点的状态
    ./rabbitmqctl cluster_status
  5. 创建并部署集群,以node2节点为例:
    ./rabbitmqctl stop_app
    ./rabbitmqctl join_cluster rabbit@node1
    ./rabbitmqctl start_app
  6. 查看集群状态
    ./rabbitmqctl cluster_status

    至此,RabbitMQ普通模式已安装完成

第六步:RabbitMQ开启图形化页面

centos7搭建rabbitmq高可用集群 rabbitmq集群部署详解_重启

从图中可以看出集群中的三个节点信息,其中两个内存节点,一个磁盘节点。另外,在memory字段显示了当前内存的使用情况和最高可以使用的内存量,同样在Disk space字段显示了磁盘空间和最低可用的磁盘空间。基于这两点,下面说一下RabbitMQ对内存和磁盘的控制。

一、内存控制

vm_memory_high_watermark该值为内存阈值,默认为0.4。意思为物理内存的40%。40%的内存并不是内存的最大的限制,它是一个发布的节制,当达到40%时Erlang会做GC。最坏的情况是使用内存80%。如果把该值配置为0,将关闭所有的publishing 。命令如下:


rabbitmqctl set_vm_memory_high_watermark 0

Paging内存阈值,该值为默认为0.5,该值为vm_memory_high_watermark的20%时,将把内存数据写到磁盘。
如机器内存16G,当RABBITMQ占用内存1.28G(16*0.4*0.2)时把内存数据放到磁盘。


二、硬盘控制

当RabbitMQ的磁盘空闲空间小于50M(默认),生产者将被BLOCK。

如果采用集群模式,磁盘节点空闲空间小于50M将导致其他节点的生产者都被block。可以通过disk_free_limit来对进行配置。

第七步:RabbitMQ镜像集群配置

上述配置的RabbitMQ默认集群模式,但并不包管队列的高可用性,尽管互换机、绑定这些可以复制到集群里的任何一个节点,然则队列内容不会复制。固然该模式解决一项目组节点压力,但队列节点宕机直接导致该队列无法应用,只能守候重启,所以要想在队列节点宕机或故障也能正常应用,就要复制队列内容到集群里的每个节点,须要创建镜像队列。

镜像队列是基于普通的集群模式的,所以你还是得先配置普通集群,然后才能设置镜像队列,我们就以上面的集群接着做。

我是通过上面开启的网页的管理端来设置的镜像队列,也可以通过命令,这里先说其中的网页设置方式:

  1. 点击admin菜单–>右侧的Policies选项–>左侧最下下边的Add/update a policy。
  2. 按照图中的内容根据自己的需求填写。
  3. 点击Add policy添加策略。

此时你就会来你的两台rabbitmq服务器的网页管理端amind菜单下看见刚才创建的队列了,下面我们来添加一个queues队列来看看效果,这里只是测试结果,其它的先不填写。

命令方式设置镜像队列策略:

  1. 在任意一个节点上执行:rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
    将所有队列设置为镜像队列,即队列会被复制到各个节点,各个节点状态保持一直。
  2. 到另一节点上查看策略:rabbitmqctl list_policies

        

centos7搭建rabbitmq高可用集群 rabbitmq集群部署详解_RabbitMQ_02

第七步:其它

端口号:   网页管理 15672     集群端口 25672   AMQP端口 5672  

访问路径:http://10.100.160.132:15672   默认超级管理员用户名/密码:guest/guest  (仅限localhost登录,不允许远程访问)

可在页面中配置交换规则、路由、队列,并对三者关系进行绑定

centos7搭建rabbitmq高可用集群 rabbitmq集群部署详解_服务器_03

配置用户名命令:

  1. 添加用户:./sbin/rabbitmqctl add_user admin admin
  2. 添加权限:./sbin/rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*"
  3. 修改用户角色:./sbin/rabbitmqctl set_user_tags admin administrator
  4. 修改密码:./sbin/rabbitmqctl  change_password admin hdadmin123
  5. 删除用户:./sbin/rabbitmqctl  delete_user admin
  6. 用户列表:./sbin/rabbitmqctl  list_users

RabbitMQ退出集群:

 假设要把rabbit@node2退出集群,在rabbit@node2上执行:

  1. rabbitmqctl stop_app
  2. rabbitmqctl reset
  3. rabbitmqctl start_app

在集群主节点上执行:

 rabbitmqctl forget_cluster_node rabbit@node2

查看cluster状态是否正常(要在所有节点上查询):

rabbitmqctl cluster_status

 

centos7搭建rabbitmq高可用集群 rabbitmq集群部署详解_服务器_04

如果有节点没加入集群,可以先退出集群,然后再重新加入集群。 

上述方法不适合内存节点重启,内存节点重启的时候是会去磁盘节点同步数据,如果磁盘节点没起来,内存节点一直失败。

磁盘节点修改为内存节点:

所有节点默认为磁盘节点(disk),如果想改为内存节点(ram),需使用以下命令:

  1. rabbitmqctl stop_app
  2. rabbitmqctl change_cluster_node_type ram
  3. rabbitmqctl start_app

一个集群中最少要有一个磁盘节点

RabbitMQ集群重启:

集群重启时,最后一个挂掉的节点应该第一个重启,如果因特殊原因(比如同时断电),而不知道哪个节点最后一个挂掉。可用以下方法重启:

先在一个节点上执行:

1. rabbitmqctl force_boot
2. service rabbitmq-server start

在其他节点上执行:

service rabbitmq-server start

rabbitmq常用命令:

1. add_user        <UserName> <Password>
2. delete_user    <UserName>
3. change_password <UserName> <NewPassword>
4. list_users
5. add_vhost    <VHostPath>
6. delete_vhost <VHostPath>
7. list_vhostsset_permissions  [-p <VHostPath>] <UserName> <Regexp> <Regexp> <Regexp>
8. clear_permissions [-p <VHostPath>] <UserName>
9. list_permissions  [-p <VHostPath>]
10. list_user_permissions <UserName>
11. list_queues    [-p <VHostPath>] [<QueueInfoItem> ...]
12. list_exchanges [-p <VHostPath>] [<ExchangeInfoItem> ...]
13. list_bindings  [-p <VHostPath>]
14. list_connections [<ConnectionInfoItem> ...]

注意事项

  • cookie在所有节点上必须完全一样,同步时一定要注意。
  • erlang是通过主机名来连接服务,必须保证各个主机名之间可以ping通。可以通过编辑/etc/hosts来手工添加主机名和IP对应关系。如果主机名ping不通,rabbitmq服务启动会失败。
  • 如果queue是非持久化queue,则如果创建queue的那个节点失败,发送方和接收方可以创建同样的queue继续运作。但如果是持久化queue,则只能等创建queue的那个节点恢复后才能继续服务。
  • 在集群元数据有变动的时候需要有disk node在线,但是在节点加入或退出的时候所有的disk node必须全部在线。如果没有正确退出disk node,集群会认为这个节点当掉了,在这个节点恢复之前不要加入其它节点。