• RabbitMQ 群集安装


    **★★★★★★http://www.rabbitmq.com/which-erlang.html (rabbitmq和erlang版本对应表)**

    # RabbitMQ 群集安装(每一台机器都操作)

    ## 一、环境描述

    ### 1、操作系统

    | 主机名 | IP地址 | 操作系统版本 | erlang 版本 | rabbitmq 版本 |
    | ------------- | ------ | ------------------------------------ | ----------- | ------------- |
    | 192.168.3.99 | node02 | CentOS Linux release 7.4.1708 (Core) | 21.0 | 3.7.7 |
    | 192.168.3.100 | node01 | CentOS Linux release 7.4.1708 (Core) | 21.0 | 3.7.7 |
    | 192.168.3.222 | node03 | CentOS Linux release 7.4.1708 (Core) | 21.0 | 3.7.7 |

    ### 2、设置linux静态IP+

    ~~~
    命令:
    # cd /etc/sysconfig/network-scripts/
    # vim ifcfg-ens33

    修改内容为:
    TYPE=Ethernet
    PROXY_METHOD=none

    BOOTPROTO=static #静态IP

    BROWSER_ONLY=no
    DEFROUTE=yes

    IPADDR=192.168.1.189 #调整
    NETMASK=255.255.255.0 #调整
    GATEWAY=192.168.1.1 #调整
    DNS1=202.106.0.20 #调整

    DNS2=8.8.8.8
    IPV4_FAILURE_FATAL=no
    IPV6INIT=yes
    IPV6_AUTOCONF=yes
    IPV6_DEFROUTE=yes
    IPV6_FAILURE_FATAL=no
    IPV6_ADDR_GEN_MODE=stable-privacy
    NAME=ens33
    UUID=312fb2fd-eade-4e6f-8abb-5602fc8d2da4
    DEVICE=ens33

    ONBOOT=yes # 支持静态IP


    修改完毕后:执行命令:
    # service network restart
    重启网卡:
    # systemctl restart network
    ~~~

    ### 3.关闭防火墙

    ~~~
    查看防火墙:
    # systemctl status firewalld.service
    开启防火墙:
    # systemctl start firewalld.service
    关闭防火墙
    # systemctl stop firewalld.service #停止firewall
    # systemctl disable firewalld.service #禁止firewall开机启动
    ~~~

    ### 3 、文件配置(每一台服务都必须配置)

    修改主机名称

    ```
    查看主机名称:
    # hostname
    修改主机名称:
    # hostnamectl set-hostname <主机名称> ## 永久修改了主机名称
    ```

    编辑/etc/hosts 文件配置

    ```
    127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
    ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
    192.168.3.220 node1
    192.168.3.221 node2
    192.168.3.222 node3
    ```

    ## 二、安装

    ### 1、安装环境依赖包

    这里虚拟机系统为Centos7,采用的安装方式是yum安装,为了简单,这里直接使用官方提供的erlang和RabbitMQ-server的自动安装脚本([官方安装文档](https://www.rabbitmq.com/install-rpm.html)),逐行执行下边的代码就可以安装完成erlang和RabbitMQ。

    ```
    安装socat
    # yum install socat
    ```

    ### 2、安装 erlang

    rabbitMQ 是用 erlang 语言写的,所以需要先安装 erlang。

    ```
    # curl -s https://packagecloud.io/install/repositories/rabbitmq/erlang/script.rpm.sh | sudo bash
    # yum -y install erlang

    测试查看版本:
    # erl

    ```

    ### 3、安装 rabbitmq

    ```
    # curl -s https://packagecloud.io/install/repositories/rabbitmq/rabbitmq-server/script.rpm.sh | sudo bash
    # yum -y install rabbitmq-server

    测试查看版本:rabbitmqctl version
    ```

    ### 4.启动rabbitmq服务

    ~~~
    启动:
    # systemctl start rabbitmq-server
    停止:
    # rabbitmqctl stop_app
    ~~~

    ### 5.添加web管理插件

    ~~~
    # rabbitmq-plugins enable rabbitmq_management
    ~~~

    ## 三、设置 rabbitMQ

    ### 1、开启 rabbitMQ web 页面访问

    ```
    # rabbitmq-plugins enable rabbitmq_management
    也可以直接将开启的插件配置写入配置文件
    # echo "[rabbitmq_management]." > /usr/local/rabbitmq/etc/rabbitmq/enabled_plugins
    ```

    ### 2、启动 rabbitmq-server

    ```
    # rabbitmq-server start # 前台启动

    ## ##
    ## ## RabbitMQ 3.7.7. Copyright (C) 2007-2018 Pivotal Software, Inc.
    ########## Licensed under the MPL. See http://www.rabbitmq.com/
    ###### ##
    ########## Logs: /usr/local/rabbitmq/var/log/rabbitmq/rabbit@node03.log
    /usr/local/rabbitmq/var/log/rabbitmq/rabbit@node03_upgrade.log

    Starting broker...
    completed with 3 plugins. # 说明 web 管理插件已经启动


    # rabbitmq-server -detached # 后台启动,不占用终端,推荐
    Warning: PID file not written; -detached was passed.7

    # rabbitmq-server start_app
    # rabbitmq-server stop_app

    默认有一个属于localhost的用户guest 密码guest,不支持远程访问,怎么解决?
    1、使用rabbitmqctl来管理用户
    ./rabbitmqctl add_user rabbit rabbit ## 添加用户
    ./rabbitmqctl set_permissions rabbit -p / ".*" ".*" ".*"
    ./rabbitmqctl set_user_tags rabbit administrator
    2、添加端口
    # firewall-cmd --add-port=5672/tcp --permanent ## rabbitmq端口
    # firewall-cmd --add-port=15672/tcp --permanent ## web管理界面端口
    # firewall-cmd --reload ## 刷新放行列表
    3、通过http://ip:15672
    输入rabbit/rabbit 进行web管界面
    ```

    ### 3、 rabbitMQ 端口

    **★这里有一个需要注意**,记得配置下hosts,在hosts里加上本机的名称。erlang进程需要host来进行连接,所以它会检查你的hosts配置。还需要设置下防火墙,三个端口要打开。**15672**是管理界面用的,**25672**是集群之间使用的端口,4369是erlang进程epmd用来做node连接的。

    ```
    1.查看放行端口:
    # firewall-cmd --list-port
    2、添加端口
    # firewall-cmd --add-port=5672/tcp --permanent ## rabbitmq端口
    # firewall-cmd --add-port=15672/tcp --permanent ## web管理界面端口
    # firewall-cmd --add-port=4369/tcp --permanent ##node通信端口
    # firewall-cmd --reload ## 刷新放行列表
    ```

    ## 四、群集配置

    ### 1、准备工作

    | IP地址 | 主机名称 | 操作系统版本 | erlang 版本 | rabbitmq 版本 |
    | ------------- | -------- | ------------------------------------ | ----------- | ------------- |
    | 192.168.3.211 | node01 | CentOS Linux release 7.4.1708 (Core) | V11.0.2 | 3.8.5 |
    | 192.168.3.212 | node02 | CentOS Linux release 7.4.1708 (Core) | V11.0.2 | 3.8.5 |
    | 192.168.3.213 | node03 | CentOS Linux release 7.4.1708 (Core) | V11.0.2 | 3.8.5 |

    编辑/etc/hosts 文件配置映射

    ~~~
    命令指定IP地址复制文件:
    # scp /etc/hosts root@192.168.3.213:/etc/hosts


    修改为以下内容:
    127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
    ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
    192.168.3.211 node1
    192.168.3.212 node2
    192.168.3.213 node3
    192.168.3.214 node4
    192.168.3.215 node5
    ~~~

    ~~~

    命令执行启动前台启动rabbitmq服务:
    # rabbitmq-server start

    命令执行启动后台启动rabbitmq服务:
    # rabbitmq-server -detached

    命令执行停止RabbitMq服务:
    # rabbitmqctl stop

    命令执行启用插件:
    # rabbitmq-plugins enable rabbitmq_management

    查看rabbitMq进程:
    # ps -ef | grep rabbitmq

    1.查看放行端口:
    # firewall-cmd --list-port

    2关闭端口:
    # firewall-cmd --permanent --zone=public --remove-port=5672/tcp
    # firewall-cmd --permanent --zone=public --remove-port=15672/tcp
    # firewall-cmd --permanent --zone=public --remove-port=4369/tcp
    # firewall-cmd --permanent --zone=public --remove-port=25672/tcp

    3、添加端口
    # firewall-cmd --add-port=5672/tcp --permanent ## rabbitmq端口
    # firewall-cmd --add-port=15672/tcp --permanent ## web管理界面端口
    # firewall-cmd --add-port=4369/tcp --permanent ##node erlang通信端口
    # firewall-cmd --add-port=25672/tcp --permanent ##node 集群节点通信

    # firewall-cmd --reload ## 刷新放行列表
    ~~~

    > 集群管理:没有明显的主从,主要是 disk 和 ram 节点的区别
    >
    > 集群要求:不支持跨网段(erlang 限制)【局域网】
    >
    > 集群类型:普通通集群、镜像集群
    >
    > - 普通集群:结构同步,消息实体只存在一个节点中,但 consumer 在非消息节点获取时,节点间存在消息拉取,易产生性能瓶颈。
    > - 镜像集群:集群中一个 master,负责调试,处理消息实体,其他节点保存一份数据到本地;性能主要靠 master 承载。
    >
    > 持久化,分两部分:
    >
    > - Rabbitmq 服务器配置持久化:默认的就是持久化(disc类型);
    > - 代码持久化:默认情况下,代码创建的消息队列和存放在队列里的消息都是非持久化的,需要在建产队列时指定

    **在配置群集前,必须保证各节点之间的主机名能够相互解析**

    RabbitMQ 节点使用域名相互寻址,因此所有群集成员的主机名必须能够从所有群集节点解析,可以修改 `/etc/hosts` 文件或者使用 DNS 解析

    如果要使用节点名称的完整主机名(RabbitMQ 默认为短名称),并且可以使用DNS解析完整的主机名,则可能需要调查设置环境变量 `RABBITMQ_USE_LONGNAME = true`

    一个群集的组成可以动态改变,所有的 RabbitMQ 开始作为单个节点运行,这些节点可以加入到群集,然后也可以再次脱离群集转加单节点。

    RabbitMQ 群集可以容忍单个节点的故障。节点可以随意启动和停止,只要它们在关闭时能和群集成员节点联系。

    **节点可以是 Disk 节点或 RAM 节点**

    RAM 节点将内部数据库表存储在 RAM 中。这不包括消息,消息存储索引,队列索引和其他节点状态,在 90% 以上的情况下,您希望所有节点都是磁盘节点;

    RAM 节点是一种特殊情况,可用于改善高排队,交换或绑定流失的性能集群。RAM 节点不提供有意义的更高的消息速率。

    由于 RAM 节点仅将内部数据库表存储在 RAM 中,因此它们必须在启动时从对等节点同步它们。这意味着**群集必须至少包含一个磁盘节点。因此无法手动删除集群中剩余的最后一个磁盘节点**

    ### 1、设置节点相互信任:Erlang Cookie

    RabbitMQ 节点和 CLI 工具(例如 rabbitmqctl )使用 cookie 来确定它们是否被允许相互通信,要使两个节点能够通信,它们必须具有相同的共享密钥,称为 Erlang Cookie。 Cookie 只是一个字符串,最多可以有 255 个字符。它通常存储在本地文件中。**该文件必须只能由所有者访问(400 权限)**。每个集群节点必须具有相同的 cookie,文件位置(rpm 安装) /var/lib/rabbitmq/.erlang.cookie,如果是源码安装的 .erlang.cookie 文件在**启动用户的家目录中**。把 rabbit2、rabbit3 设置成和 rabbit1 一样的即可,权限是 400 ,或者直接复制一份过去即可。

    ```
    这里采用复制的方式

    命令Copy文件:scp /var/lib/rabbitmq/.erlang.cookie root@192.168.3.212:/var/lib/rabbitmq


    采用源码安装的 rabbitmq .erlang.cookie 文件在 /root 目录下
    # scp /root/.erlang.cookie node02:/root/
    root@node02's password:
    .erlang.cookie 100% 20 2.3KB/s 00:00
    # scp /root/.erlang.cookie node03:/root/
    root@node03's password:
    .erlang.cookie 100% 20 7.5KB/s 00:00
    ```

    ### 2、正常方式启动所有节点

    ```
    # rabbitmq-server -detached #后台启动 在所有节点上启动 rabbitmq-server
    ```

    ### 3、查看群集状态

    ```
    # nod01 上
    # rabbitmqctl cluster_status
    Cluster status of node rabbit@node01 ...
    [{nodes,[{disc,[rabbit@node01]}]},
    {running_nodes,[rabbit@node01]},
    {cluster_name,<<"rabbit@node01">>},
    {partitions,[]},
    {alarms,[{rabbit@node01,[]}]}]

    # node02 上
    # ./rabbitmqctl cluster_status
    Cluster status of node rabbit@node02 ...
    [{nodes,[{disc,[rabbit@node02]}]},
    {running_nodes,[rabbit@node02]},
    {cluster_name,<<"rabbit@node02">>},
    {partitions,[]},
    {alarms,[{rabbit@node02,[]}]}]

    # node03 上
    # ./rabbitmqctl cluster_status
    Cluster status of node rabbit@node03 ...
    [{nodes,[{disc,[rabbit@node03]}]},
    {running_nodes,[rabbit@node03]},
    {cluster_name,<<"rabbit@node03">>},
    {partitions,[]},
    {alarms,[{rabbit@node03,[]}]}]
    ```

    ### 4、将 node02、node03 加入 rabbit@node01 群集

    #### a. 停止 node02 的 rabbitmq 应用程序

    ```
    # 在其余 2 个节点上操作
    关闭所有rabbitmq进程: pkill rabbitmq
    根据进程ID关闭进程: kill -9 9038

    # rabbitmqctl stop_app
    Stopping rabbit application on node rabbit@node02 ...
    ```

    #### b. 加入 rabbit@node01 群集1

    ```
    # 在其余 2 个节点上操作
    # rabbitmqctl join_cluster rabbit@node01
    # 如果这一步报错的话,请在所有节点打开相应的端口,打开 4369 端口 (Refuse Access),解决方式
    # firewall-cmd --add-port=4369/tcp --permanent
    # firewall-cmd --reload
    Clustering node rabbit@node02 with rabbit@node01
    ```

    #### c. 启动 rabbitMQ 程序

    ```
    # 在其余 2 个节点上操作
    # rabbitmqctl start_app
    Starting node rabbit@node02 ...
    completed with 3 plugins.
    ```

    #### b. 查看群集状态

    ```
    在群集任何一个节点上都可以查看到群集的状态
    # rabbitmqctl cluster_status
    Cluster status of node rabbit@node01 ...
    [{nodes,[{disc,[rabbit@node01,rabbit@node02,rabbit@node03]}]},
    {running_nodes,[rabbit@node03,rabbit@node02,rabbit@node01]},
    {cluster_name,<<"rabbit@node01">>},
    {partitions,[]},
    {alarms,[{rabbit@node03,[]},{rabbit@node02,[]},{rabbit@node01,[]}]}]
    ```

    通过上面的步骤,我们可以在群集运行的同时随时向群集添加新节点

    已加入群集的节点可以随时停止,也可以崩溃。在这两种情况下,群集的其余部分都会继续运行,并且节点在再次启动时,会自动 ”跟上“(同步)其它群集节点。

    > 注意:
    >
    > 当整个集群关闭时,最后一个关闭的节点必须是第一个启动的节点,如果不是这样,节点会等待 30s 等待最后的磁盘节点恢复状态,然后失败。如果最后下线的节点不能上线,可以使用 forget_cluster_node 命令将其从群集中删除。如果所有的节点不受控制的同时宕机,比如掉电,会进入所有的节点都会认为其他节点比自己宕机的要晚,即自己先宕机,这种情况下可以使用 force_boot 指令来启动一个节点。

    #### d. 设置群集模式为"镜像队列"模式

    ```
    # rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all","ha-sync-mode":"automatic"}'

    rabbitmqctl set_policy [-p Vhost] Name Pattern Definition [Priority]
    -p Vhost: 可选参数,针对指定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的优先级
    ```

    > ```
    > ha-sync-mode`: 如果此节点不进行设置,在其中一台服务器宕机再启动后 会报 Unsynchronised Mirrors XXXX 错误。这时候在队列详细信息页面需要手动点击同步队列,或者用命令行执行命令 `rabbitmqctl sync_queue name
    > ```

    ## 五、群集移除节点

    当节点不再是节点的一部分时,需要从群集中明确地删除节点。

    将 rabbit@node02 从群集中删除,回到独立模式:

    ```
    在 rabbit@node02 上操作:
    1、停止 RabbitMQ 应用程序。
    # rabbitmqctl stop_app
    Stopping rabbit application on node rabbit@node02 ...

    2、重置节点。
    # rabbitmqctl reset
    Resetting node rabbit@node02 ...

    3、重新启动 RabbitMQ 应用程序。
    # rabbitmqctl start_app
    Starting node rabbit@node02 ...
    completed with 3 plugins.

    4、在节点上运行 cluster_status 命令,确认 rabbit@node02 现在已经不再是群集的一部分,并独立运行
    # rabbitmqctl cluster_status
    Cluster status of node rabbit@node02 ...
    [{nodes,[{disc,[rabbit@node02]}]},
    {running_nodes,[rabbit@node02]},
    {cluster_name,<<"rabbit@node02">>},
    {partitions,[]},
    {alarms,[{rabbit@node02,[]}]}]
    ```

    也可以远程删除节点,例如,在处理无响应的节点时,这很有用。

    例如,在节点 rabbit@node01 上把 rabbit@node03 从群集中移除

    ```
    1、先在 rabbit@node03 上将 RabbitMQ 应用停掉
    # rabbitmqctl stop_app
    Stopping rabbit application on node rabbit@node03 ...

    2、在 rabbit@node01 上远程将 rabbit@node03 删除
    # rabbitmqctl forget_cluster_node rabbit@node03
    Removing node rabbit@node03 from the cluster

    3、请注意,这时,rabbit@node03 仍然认为它还在 rabbit@node01 的群集里面,并试图启动它,这将会导致错误。我们需要将 rabbit@node03 重新设置才能重新启动它。(在 rabbit@node03 上操作)
    # rabbitmqctl reset
    Resetting node rabbit@node03 ...

    4、重新启动 rabbit@node03
    # rabbitmqctl start_app
    Starting node rabbit@node03 ...
    completed with 3 plugins.
    ```

    现在,三个节点都是作为独立的节点在运行。

    > 注意:此时,rabbit@node01 保留了簇的剩余状态,而 rabbit@node02 和 rabbit@node03 是刚刚初始化的 RabbitMQ。如果想重新初始化 rabbit@node01 的话,需要按照与其它节点相同的步骤进行即可:
    >
    > 1、停止 RabbitMQ 应用程序
    >
    > 2、 重置 RabbitMQ
    >
    > 3、启动 RabbitMQ 应用程序

    ## 六、RabbitMQ 管理

    ### 1、主机名更改

    RabbitMQ 节点使用主机名相互通信。因此,所有节点名称必须能够解析所有群集对应的名称。像 rabbitmqctl 这样的工具也是如此。除此之外,**默认情况下 RabbitMQ 使用系统的当前主机名来命名数据库目录。如果主机名更改,则会创建一个新的空数据库。**为了避免数据丢失,建立一个固定和可解析的主机名至关重要。每当主机名更改时,应该重新启动 RabbitMQ。如果要使用节点名称的完整主机名(RabbitMQ 默认为短名称),并且可以使用 DNS 解析完整的主机名,则需要修改设置环境变量 `RABBITMQ_USE_LONGNAME=true`

    ### 2、RAM 节点的群集

    RAM 节点只将其元数据保存在内存中。 只有 RAM 节点的集群是脆弱的, 如果群集停止,将无法再次启动, 并将丢失所有数据。

    **创建 RAM 节点**

    我们可以在首次加入集群时将节点声明为 RAM 节点。像之前一样,我们使用 rabbitmqctl join_cluster 来完成此 操作,但传递 --ram 标志

    ```
    [root@node03 escript]# rabbitmqctl stop_app
    Stopping rabbit application on node rabbit@node03 ...

    [root@node03 escript]# rabbitmqctl join_cluster --ram rabbit@node01
    Clustering node rabbit@node03 with rabbit@node01

    [root@node03 escript]# rabbitmqctl start_app
    Starting node rabbit@node03 ...
    completed with 3 plugins.

    [root@node03 escript]# rabbitmqctl cluster_status
    Cluster status of node rabbit@node03 ...
    [{nodes,[{disc,[rabbit@node01]},{ram,[rabbit@node03]}]},
    {running_nodes,[rabbit@node01,rabbit@node03]},
    {cluster_name,<<"rabbit@node01">>},
    {partitions,[]},
    {alarms,[{rabbit@node01,[]},{rabbit@node03,[]}]}]
    ```

    **更改节点类型**

    可以将节点的类型 RAM 更改为 disc,反之亦然。

    使用 `change_cluster_node_type` 命令。

    ```
    [root@node03 escript]# ./rabbitmqctl stop_app
    Stopping rabbit application on node rabbit@node03 ...

    [root@node03 escript]# ./rabbitmqctl change_cluster_node_type disc
    Turning rabbit@node03 into a disc node

    [root@node03 escript]# ./rabbitmqctl start_app
    Starting node rabbit@node03 ...
    completed with 3 plugins.

    [root@node03 escript]# ./rabbitmqctl cluster_status
    Cluster status of node rabbit@node03 ...
    [{nodes,[{disc,[rabbit@node01,rabbit@node03]}]},
    {running_nodes,[rabbit@node01,rabbit@node03]},
    {cluster_name,<<"rabbit@node01">>},
    {partitions,[]},
    {alarms,[{rabbit@node01,[]},{rabbit@node03,[]}]}]
    ```

    **常用管理命令**

    - 用户权限管理

    RabbitMQ 有一个默认的用户'guest',密码也是"guest",这个用户默认只能通过本机访问,如:`http://localhost:15672`,在通过 http 访问之前记得启用 management 插件。

    要让其他机器可以访问,需要创建一个新用户,并为其分配权限。

    1. 用户管理

    > rabbitmqctl list_users # 列出所有用户
    >
    > rabbitmqctl add_user {username} {password} # 添加用户
    >
    > rabbitmqctl delete_user {username} # 删除用户
    >
    > rabbitmqctl change_password {username} {newpassword} # 修改密码
    >
    > rabbitmqctl authenticate_user {username} {password} # 用户认证
    >
    > rabbitmqctl clear_password {username} # 删除密码,密码删除后就不能访问了。
    >
    > rabbitmqctl set_user_tags {username} {tag ...} # 为用户设置角色,tag 可以是 0 个,一个,或多个。如:`rabbitmqctl set_user_tags chris administrator`,设置为管理员;`rabbitmqctl set_user_tags chris` ,清除 chris 与角色的关联。

    2. 权限管理

    RabbitMQ 客户端连接到一个服务端的时候,在它的操作指令中指定了一个虚拟主机。服务端首先检查是否有访问该虚拟主机的权限,没有权限的会拒绝连接。

    对于 exchanges 和 queues 等资源,位于某个虚拟主机内;不同虚拟主机内即便名称相同也代表不同的资源。当特定操作在资源上执行时第二级访问控制开始生效。

    RabbitMQ 在某个资源上区分了配置、写和读操作。配置操作创建或者销毁资源,或者更改资源的行为。写操作将消息注入进资源之中。读操作从资源中获取消息。

    要执行特定操作用户必须授予合适的权限。

    > rabbitmqctl list_vhosts [vhost info item ...] # 获取 vhosts 列表
    >
    > rabbitmqctl add_vhost {vhost} # 添加 vhosts
    >
    > rabbitmqctl delete_vhost {hosts} # 删除 vhosts
    >
    > rabbitmqctl set_permissions [-p vhost] {user} {conf} {write} {read} # 给用户分配对应的 vhost 上分配相应的权限。如:`rabbitmqctl set_permissions -p /myvhost chris "^chris-.*" ".*" ".*"`
    >
    > rabbitmqctl clear_permissions [-p vhost] {username} # 清除权限
    >
    > rabbitmqctl list_permissions [-p vhost] # 清除权限列表
    >
    > rabbitmqctl list_user_permissions {username} # user 权限列表
    >
    > `rabbitmqctl set_permissions -p / chris ".*" ".*" ".*"` 此时用户chris才有访问队列资源的权限

    ## 七、高可用配置

    ![1646a2dbbc08e9c6](assets/1646a2dbbc08e9c6.png)

    ### 7.1、安装配置HaProxy

    yum install haproxy

    ### 7.2、安装配置Keepalived

    #### HAproxy负载

    > 在`192.168.1.219`和`192.168.1.220`做负载

    - 安装HAproxy

    ```
    [root@rabbit1 tmp] yum install haproxy
    // 编辑配置文件
    [root@rabbit1 tmp] vim /etc/haproxy/haproxy.cfg
    ```

    在最后新增配置信息:

    ```
    #######################HAproxy监控页面#########################
    listen http_front
    bind 0.0.0.0:1080 #监听端口
    stats refresh 30s #统计页面自动刷新时间
    stats uri /haproxy?stats #统计页面url
    stats realm Haproxy Manager #统计页面密码框上提示文本
    stats auth admin:Guo*0820 #统计页面用户名和密码设置
    #stats hide-version #隐藏统计页面上HAProxy的版本信息

    #####################我把RabbitMQ的管理界面也放在HAProxy后面了###############################
    listen rabbitmq_admin
    bind 0.0.0.0:15673
    server node1 192.168.3.220:15672
    server node2 192.168.3.221:15672
    server node3 192.168.3.222:15672

    #####################RabbitMQ服务代理###########################################
    listen rabbitmq_cluster 0.0.0.0:5673
    mode tcp
    stats enable
    balance roundrobin
    #option tcpka
    #option tcplog
    timeout client 3h
    timeout server 3h
    timeout connect 3h
    #balance url_param userid
    #balance url_param session_id check_post 64
    #balance hdr(User-Agent)
    #balance hdr(host)
    #balance hdr(Host) use_domain_only
    #balance rdp-cookie
    #balance leastconn
    #balance source //ip
    server node1 192.168.3.220:5672 check inter 5s rise 2 fall 3 #check inter 5000 是检测心跳频率,rise 2是2次正确认为服务器可用,fall 3是3次失败认为服务器不可用
    server node2 192.168.1.221:5672 check inter 5s rise 2 fall 3
    server node3 192.168.1.222:5672 check inter 5s rise 2 fall 3
    ```

    - 启动HAproxy负载

    ```
    [root@rabbit1 tmp] haproxy -f /etc/haproxy/haproxy.cfg
    ```

    - HAproxy负载完毕

    #### Keepalived安装

    > 利用keepalived做主备,避免单点问题,实现高可用
    > 在 `192.168.1.219`和`192.168.1.220`做主备,前者主,后者备

    - 安装Keepalived

    ```
    [root@rabbit1 tmp] yum -y install keepalived
    ```

    - 配置Keepalived生成VIP

    ```
    [root@rabbit1 tmp] vim /etc/keepalived/keepalived.conf
    ```

    部分配置信息(只显示使用到的):

    ```
    global_defs {
    notification_email {
    acassen@firewall.loc
    failover@firewall.loc
    sysadmin@firewall.loc
    }

    notification_email_from Alexandre.Cassen@firewall.loc
    smtp_server 192.168.200.1
    smtp_connect_timeout 30
    router_id LVS_DEVEL
    vrrp_skip_check_adv_addr
    # vrrp_strict # 注释掉,不然访问不到VIP
    vrrp_garp_interval 0
    vrrp_gna_interval 0
    }

    # 检测任务
    vrrp_script check_haproxy {
    # 检测HAProxy监本
    script "/etc/keepalived/script/check_haproxy.sh"
    # 每隔两秒检测
    interval 2
    # 权重
    weight 2
    }

    # 虚拟组
    vrrp_instance haproxy {
    state MASTER # 此处为`主`,备机是 `BACKUP`
    interface enp4s0f0 # 物理网卡,根据情况而定
    mcast_src_ip 192.168.1.219 # 当前主机ip
    virtual_router_id 51 # 虚拟路由id,同一个组内需要相同
    priority 100 # 主机的优先权要比备机高
    advert_int 1 # 心跳检查频率,单位:秒
    authentication { # 认证,组内的要相同
    auth_type PASS
    auth_pass 1111
    }
    # 调用脚本
    track_script {
    check_haproxy
    }
    # 虚拟ip,多个换行
    virtual_ipaddress {
    192.168.1.222
    }
    }
    ```

    - `/etc/keepalived/script/check_haproxy.sh`内容

    ```
    #!/bin/bash
    LOGFILE="/var/log/keepalived-haproxy-status.log"
    date >> $LOGFILE
    if [ `ps -C haproxy --no-header |wc -l` -eq 0 ];then
    echo "warning: restart haproxy" >> $LOGFILE
    haproxy -f /etc/haproxy/haproxy.cfg
    sleep 2

    if [ `ps -C haproxy --no-header |wc -l` -eq 0 ];then
    echo "fail: check_haproxy status" >> $LOGFILE
    systemctl stop keepalived
    fi
    else
    echo "success: check_haproxy status" >> $LOGFILE
    fi
    ```

    **解释说明:**

    > `Keepalived`组之间的心跳检查并不能察觉到`HAproxy`负载是否正常,所以需要使用此脚本。
    > 在`Keepalived`主机上,开启此脚本检测`HAproxy`是否正常工作,如正常工作,记录日志。
    > 如进程不存在,则尝试重启`HAproxy`,两秒后检测,如果还没有则关掉主`Keepalived`,此时备`Keepalived`检测到主`Keepalive`挂掉,接管VIP,继续服务

    ## 常用命令附录

    ### 常用命令

    ~~~
    查看rabbitMq进程:
    # ps -ef | grep rabbitmq

    后台启动Rabbitmq Server
    # rabbitmq-server -detached # 在所有节点上启动

    查看放行端口:
    # firewall-cmd --list-port

    命令执行启用插件:
    # rabbitmq-plugins enable rabbitmq_management

    设置为内存节点:
    # rabbitmqctl change_cluster_node_type ram
    ~~~

  • 相关阅读:
    Android应用插件式开发解决方法
    给windows服务打包,并生成安装程序
    如何在VS2013中新建WindowsService定时任务
    从源代码分析Android-Universal-Image-Loader图片下载技巧
    Android内存溢出解决方案(OOM)
    Android网络传输中必用的两个加密算法:MD5 和 RSA (附java完成测试代码)
    Volley的基本用法
    Redis 5种数据类型,2种特殊数据处理策略
    SiteWhere物联网云平台架构
    杭电1276 士兵队列训练问题
  • 原文地址:https://www.cnblogs.com/Robert-huge/p/13957887.html
Copyright © 2020-2023  润新知