1. 安装

1.1. 启动RabbitMQ容器

在容器中启动一个RabbitMQ服务的场景一般仅仅用于学习RabbitMQ简单用法,比如熟悉管理台界面、使用rabbitmq做开发测试等,生产中不会使用!

  1. # 启动rabbitmq-server
  2. # 注意事项:
  3. # 1. 需要指定主机名,数据存储目录为: rabbit@contaner_hostname
  4. # 2. 如果需要启用管理台,可以直接下载以 management 结尾的镜像
  5. # 3. 指定默认用户名密码
  6. # 4. 5627:rabbtimq-server端口,15672:web管理台端口
  7. # 更多配置参考镜像仓库中的描述
  8. [root@duduniao ~]# docker container run -d --rm --name rabbitmq-server -h my-rabbitmq -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=123456 -v /data/database/rabbitmq:/var/lib/rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3.8.9-management
  9. # 启动日志
  10. [root@duduniao ~]# docker logs rabbitmq-server
  11. Licensed under the MPL 2.0. Website: https://rabbitmq.com
  12. ## ## RabbitMQ 3.8.9
  13. ## ##
  14. ########## Copyright (c) 2007-2020 VMware, Inc. or its affiliates.
  15. ###### ##
  16. ########## Licensed under the MPL 2.0. Website: https://rabbitmq.com
  17. Doc guides: https://rabbitmq.com/documentation.html
  18. Support: https://rabbitmq.com/contact.html
  19. Tutorials: https://rabbitmq.com/getstarted.html
  20. Monitoring: https://rabbitmq.com/monitoring.html
  21. Logs: <stdout>
  22. Config file(s): /etc/rabbitmq/rabbitmq.conf
  23. Starting broker...2021-01-19 14:10:30.764 [info] <0.272.0>
  24. node : rabbit@my-rabbitmq
  25. home dir : /var/lib/rabbitmq
  26. config file(s) : /etc/rabbitmq/rabbitmq.conf
  27. cookie hash : cdswSNJ2J69EmMJEabMhiQ==
  28. log(s) : <stdout>
  29. database dir : /var/lib/rabbitmq/mnesia/rabbit@my-rabbitmq

image.png

1.2. 虚拟机中安装RabbitMQ集群(重点)

一般为了保证高可用,以及RabbitMQ的性能,都会使用集群部署。本次实验使用Ubutnu 1804系统安装。官方文档:https://www.rabbitmq.com/install-debian.html
Ansible Roles: https://github.com/mrlesmithjr/ansible-rabbitmq

1.2.1. 资源配置

image.png

1.2.2. 安装过程

1.2.2.1. 依赖项

RabbitMQ的安装依赖于Erlang语言,Erlang语言的版本和RabbitMQ的版本存在依赖关系,需要提前确定好:
image.png

1.2.2.2. 安装方式

安装官方的说法,可以使用 二进制文件或者apt仓库安装,但是在国内使用RabbitMQ的官方源,速度非常慢,Erlang的下载速度也非常慢。目前我个人推荐的方案是:

  • Erlang:使用清华大学的源进行安装,目前国内也只发现了这一家
  • RabbitMQ:使用二进制文件直接进行安装, apt-get install -f xx ,目前国内没有可用的源(较老版本的不算)

    1.2.2.3. 准备工作

    三台机器,都配置好 阿里云的源,并更新缓存!

    root@ubuntu-7-60:~# cat /etc/apt/sources.list
    deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
    deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
    deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
    deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
    deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
    deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
    deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
    deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
    deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
    deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
    root@ubuntu-7-60:~# apt-get update
    

    1.2.2.4. 配置erlang源

    三台机器都需要操作

    root@ubuntu-7-60:~# apt-add-repository "deb https://mirrors.tuna.tsinghua.edu.cn/erlang-solutions/ubuntu/ bionic contrib"
    root@ubuntu-7-60:~# apt-get install -y erlang-base \
      erlang-asn1 erlang-crypto erlang-eldap erlang-ftp erlang-inets \
      erlang-mnesia erlang-os-mon erlang-parsetools erlang-public-key \
      erlang-runtime-tools erlang-snmp erlang-ssl \
      erlang-syntax-tools erlang-tftp erlang-tools erlang-xmerl
    

    1.2.2.5. 安装rabbitmq-server

    因为官方仓库下载地址太慢,建议使用二进制文件安装,官方的二进制包在Github可下载:https://github.com/rabbitmq/rabbitmq-server/releases
    两种方案:

  • 从github下载,可能速度很慢

  • 从华为的镜像站点下载:https://mirrors.huaweicloud.com/rabbitmq-server

三台机器都需要安装

root@ubuntu-7-60:~# wget https://mirrors.huaweicloud.com/rabbitmq-server/v3.8.9/rabbitmq-server_3.8.9-1_all.deb
root@ubuntu-7-60:~# apt-get install -y -f /root/rabbitmq-server_3.8.9-1_all.deb
root@ubuntu-7-60:~# rabbitmqctl version
3.8.9
root@ubuntu-7-60:~# systemctl start rabbitmq-server.service && systemctl enable rabbitmq-server.service
root@ubuntu-7-60:~# rabbitmq-plugins enable rabbitmq_management # 启动管理台功能
root@ubuntu-7-60:~# netstat -lntp|grep 5672
tcp        0      0 0.0.0.0:25672           0.0.0.0:*               LISTEN      2769/beam.smp       
tcp        0      0 0.0.0.0:15672           0.0.0.0:*               LISTEN      2769/beam.smp       
tcp6       0      0 :::5672                 :::*                    LISTEN      2769/beam.smp

1.2.2.6. 组建集群

1. 添加/etc/hosts对主机名的解析(三台机器都需要操作)
root@ubuntu-7-60:~# cat /etc/hosts # 追加一下内容
10.4.7.60 ubuntu-7-60
10.4.7.61 ubuntu-7-61
10.4.7.62 ubuntu-7-62

2. 停止app(三台机器都需要操作)
root@ubuntu-7-60:~# rabbitmqctl stop_app
Stopping rabbit application on node rabbit@ubuntu-7-60 ...

3. 停止rabbitmq服务(三台机器都需要操作)
root@ubuntu-7-60:~# systemctl stop rabbitmq-server.service

4. 同步master的cookie到salve上
root@ubuntu-7-60:~# scp /var/lib/rabbitmq/.erlang.cookie 10.4.7.61:/var/lib/rabbitmq/.erlang.cookie                                                                                                                                    100%   20    18.9KB/s   00:00    
root@ubuntu-7-60:~# scp /var/lib/rabbitmq/.erlang.cookie 10.4.7.62:/var/lib/rabbitmq/.erlang.cookie

5. 启动rabbitmq服务(三台机器都需要操作)
root@ubuntu-7-60:~# systemctl start rabbitmq-server.service
root@ubuntu-7-60:~# rabbitmqctl stop_app
root@ubuntu-7-60:~# rabbitmqctl reset

6. 加入集群
root@ubuntu-7-60:~# rabbitmqctl start_app
root@ubuntu-7-61:~# rabbitmqctl join_cluster "rabbit@ubuntu-7-60"
root@ubuntu-7-62:~# rabbitmqctl join_cluster "rabbit@ubuntu-7-60"

7. 查看集群状态
root@ubuntu-7-60:~# rabbitmqctl cluster_status
Cluster status of node rabbit@ubuntu-7-60 ...
Basics

Cluster name: rabbit@ubuntu-7-60

Disk Nodes

rabbit@ubuntu-7-60
rabbit@ubuntu-7-61
rabbit@ubuntu-7-62

Running Nodes

rabbit@ubuntu-7-60
rabbit@ubuntu-7-61
rabbit@ubuntu-7-62

Versions

rabbit@ubuntu-7-60: RabbitMQ 3.8.9 on Erlang 23.2.1
rabbit@ubuntu-7-61: RabbitMQ 3.8.9 on Erlang 23.2.1
rabbit@ubuntu-7-62: RabbitMQ 3.8.9 on Erlang 23.2.1

Maintenance status

Node: rabbit@ubuntu-7-60, status: not under maintenance
Node: rabbit@ubuntu-7-61, status: not under maintenance
Node: rabbit@ubuntu-7-62, status: not under maintenance

1.2.2.7. 创建用户并登录

root@ubuntu-7-60:~# rabbitmqctl add_user root 123456
Adding user "root" ...
root@ubuntu-7-60:~# rabbitmqctl  set_user_tags root administrator
Setting tags for user "root" to [administrator] ...

image.png

1.3. K8S中安装RabbitMQ集群


2. 基本概念和使用

2.1. 基本概念和web管理台操作

参考:https://www.yuque.com/duduniao/go/mtg1th#qWDLn

2.2. 命令行客户端

2.2.1. rabbitmq-plugins

rabbitmq-plugins 用于插件管理,插件用于增强rabbitmq-server的功能,如协议、管理台、监控等等。

1. rabbitmq-plugins list 列出所有插件

2. rabbitmq-plugins enable <plugin_name> 启用插件

3. rabbitmq-plugins disable <plugin_name> 关闭插件

4. 插件目录查看
  root@ubuntu-7-60:~# rabbitmq-plugins directories
  Listing plugin directories used by node rabbit@ubuntu-7-60
  Plugin archives directory: /usr/lib/rabbitmq/plugins:/usr/lib/rabbitmq/lib/rabbitmq_server-3.8.9/plugins # 压缩的插件目录
  Plugin expansion directory: /var/lib/rabbitmq/mnesia/rabbit@ubuntu-7-60-plugins-expand                   # 第三方插件目录
  Enabled plugins file: /etc/rabbitmq/enabled_plugins                                                      # 当前启用的插件列表

2.2.2. rabbitmqctl

rabbitmqctl 用于rabbitmq的服务、用户、策略管理等,功能非常强大,是最常用的管理工具!

2.2.2.1. 核心资源管理

1. 创建vhost: rabbitmqctl add_vhost <vhost_name>
2. 删除vhost: rabbitmqctl delete_vhost <vhost_name>
3. 列出vhost: rabbitmqclt list_vhosts
4. 查看其它信息: rabbitmqctl list_exchanges|list_queues|list_bindings|list_channels|list_connections|list_consumers
# 创建vhosts
  root@ubuntu-7-60:~# rabbitmqctl add_vhost v-1
  root@ubuntu-7-60:~# rabbitmqctl add_vhost v-2

# 查看vhosts
  root@ubuntu-7-60:~# rabbitmqctl list_vhosts -q
  name
  v-2
  /
  v-1

# 查看交换机
  root@ubuntu-7-60:~# rabbitmqctl list_exchanges --vhost v-1 -q|column -t
  name                type
  amq.fanout          fanout
  amq.match           headers
  amq.direct          direct
  amq.topic           topic
  direct
  amq.rabbitmq.trace  topic
  amq.headers         headers

# 删除vhost
  root@ubuntu-7-60:~# rabbitmqctl delete_vhost v-2
  Deleting vhost "v-2" ...
  root@ubuntu-7-60:~# rabbitmqctl list_vhosts -q|column -t
  name
  /
  v-1

2.2.2.2. 用户管理

rabbitmq 的用户角色分类:

  • 超级管理员(administrator): 具备所有权限
  • 监控者(monitoring): 包含management的所有权限,并且可以看到所有连接、信道及节点相关的信息
  • 策略配置者(policymaker): 包含management的所有权限,并且可以管理策略和参数
  • 普通管理者(management): 可以登陆管理台
  • 普通用户(none): 就是常说的普通消费者和生产者,不具备特殊角色 ```
  1. 查看用户: rabbitmqctl list_users
  2. 创建用户: rabbitmqctl add_user
  3. 删除用户: rabbitmqctl delete_user
  4. 修改密码: rabbitmqctl change_password

  5. 为用户设置角色: rabbitmqctl set_user_tags […]

  6. 为用户设置权限(针对某个虚拟主机下的exchange、queue的读写和管理权限) rabbitmqctl set_permissions [—vhost ]

    —vhost: 指定作用于的虚拟主机,默认为 /

    username: 用户名

    conf: 可以配置的资源名称,通常指队列、交换机,支持正则表达式

    write: 对哪些对象具备写权限,支持正则表达

    read: 对哪些对象具备读权限,支持正则表达

    创建用户

    root@ubuntu-7-60:~# rabbitmqctl add_user zhangsan ‘Rabbitmq@123’ root@ubuntu-7-60:~# rabbitmqctl list_users -q |column -t user tags guest [administrator] zhangsan [] root [administrator]

设置角色(如果只是普通的消费者和生产者,不需要设定角色)

root@ubuntu-7-60:~# rabbitmqctl set_user_tags zhangsan monitoring policymaker Setting tags for user “zhangsan” to [monitoring, policymaker] … root@ubuntu-7-60:~# rabbitmqctl list_users -q |column -t user tags guest [administrator] zhangsan [monitoring, policymaker] root [administrator]

设置用户资源读写权限

root@ubuntu-7-60:~# rabbitmqctl add_vhost devops root@ubuntu-7-60:~# rabbitmqctl add_user deploy-service ‘deploy@rabbitmq’ root@ubuntu-7-60:~# rabbitmqctl set_permissions deploy-service —vhost devops “deploy-.“ “.“ “.“ root@ubuntu-7-60:~# rabbitmqctl list_user_permissions deploy-service -q vhost configure write read devops deploy-. . .

<a name="Wv2vV"></a>
#### 2.2.2.3. rabbitctl 服务管理
搞清楚两个概念:

- rabbitmq 节点:或者叫叫 Erlang 节点,是运行rabbitmq程序的容器,类似于 Java虚拟机
- rabbitmq 应用:真正运行rabbitmq的服务
```go
1.    启动/停止节点和应用
    systemctl start rabbitmq-server
    systemctl stop rabbitmq-server
    rabbitmqctl stop         # 需要PID文件
    rabbitmqctl shutdown    # 不需要PID文件

2.    启动/停止应用
    rabbitmqctl start_app
    rabbitmqctl stop_app
    rabbitmqctl status

3.    管理应用
    rabbitmqctl reset              # 重置节点
    rabbitmqctl rotate_logs      # 轮转日志        

4.    集群管理
    rabbitmqctl cluster_status
    rabbitmqctl join_cluster [--disc|--ram] <existing_cluster_member>  # 加入集群,可以选择节点类型(disc 数据存在disk中,ram 数据存在ram中,默认为disk)

3. 高可用方案

在1.2中安装的rabbitmq集群,其实实现的是节点高可用,当master宕机时,其他两个节点上并不存储 Exchange 和 Queue 数据,导致节点宕机后无法正常工作。目前解决方案有两种,一种是镜像队列,一种是仲裁队列。仲裁队列是 3.8 版本引入,采用 raft 共识算法保证数据的高可用性,目前相关资料不多,推出的时间比较短,暂时不推荐使用。

3.1. 镜像队列

官方文档:https://www.rabbitmq.com/ha.html

3.1.1. 理论

3.1.1.1. 概念

在RabbitMQ Cluster中创建一个队列时,需要指定该队列创建在哪个节点上,之后该队列的消息数据将存储在该节点上,并不会同步到集群中其他节点,一旦该节点出现异常,该队列将不可用。为了提高队列的可用性,可以创建镜像队列,此时就组成的一个队列集群,一个Master队列+多个Mirror队列。
客户端操作的是Master队列,而master队列的变化会同步到所有的Mirror队列,因此需要注意的是,镜像队列并不是提供负载均衡能力,而且提供高可用能力。一旦master队列挂了,将从mirror队列中选择一个被创建最久的队列作为新的master队列。镜像队列涉及到rabbitmq cluster集群内部节点之间的数据复制,因此性能比非镜像队列要差!独占队列随着连接断开会自动删除,因此独占队列是不会被镜像的!当master队列宕机时,master上ack还没有同步到mirror时,发生切换,会导致部分消息重新发送,此处需要业务程序自行处理!

3.1.1.2. 配置镜像队列

镜像队列是通过配置策略实现的,策略可以随时修改的。设置镜像队列,需要两个参数: ha-modeha-params ,后者是可选的。配置如下:

ha-mode ha-params Result
exactly count 指定master+mirror队列的总数,当count=1则仅master队列,一般来说综合考虑性能和可用性,三节点设置2,五节点设置3
all 在所有节点都保留副本,这种方案比较保守,节点数量少的时候还行,节点数量多了,性能很差。推荐使用仲裁队列替换该方案
nodes node_names 指定镜像队列存储到哪些节点,格式 rabbit@hostname ,当节点都不可用时,将在客户端连接的节点上创建队列。
这种模式下,更新策略可能导致master节点不在新策略的node列表中,此会发生旧master节点数据迁移到新的master上。

ha-sync-mode 表示新的镜像队列同步模式:

  • manual 默认配置,表示新增的mirror队列不会同步master上的旧数据,只有当master上旧数据消费完毕后,master和mirror数据才一致。在master和mirror数据一致之前,如果master异常,则会丢失数据。管理员可以手动同步数据。
  • automatic 新的mirror队列会自动同步master上的旧数据,这个操作会阻塞队列,直到同步完成!仅在队列长度小、网络速度快且优化了 ha-sync-batch-size的情况下推荐使用

    3.1.2. 实操

    创建测试的vhosts(一般生产中,极少使用 / vhost), rabbitmqctl add_vhost mirror ,设置策略时,使用正则表达式

    3.1.2.1. 配置exactly模式

    ```

    配置策略: mirror中所有以 exa. 开通的队列使用该策略

    root@ubuntu-7-60:~# rabbitmqctl set_policy —vhost mirror ha-exa “^exa.“ ‘{“ha-mode”:”exactly”,”ha-params”:2}’ Setting policy “ha-exa” for pattern “^exa.“ to “{“ha-mode”:”exactly”,”ha-params”:2}” with priority “0” for vhost “mirror” …

查看策略

root@ubuntu-7-60:~# rabbitmqctl list_policies —vhost mirror Listing policies for vhost “mirror” … vhost name pattern apply-to definition priority mirror ha-exa exa-.* all {“ha-mode”:”exactly”,”ha-params”:2} 0

创建queue

参考图片 add new queue

查看queue的策略

root@ubuntu-7-60:~# rabbitmqctl list_queues —vhost mirror policy pid slave_pids Timeout: 60.0 seconds … Listing queues for vhost mirror … policy pid slave_pids ha-exa rabbit@ubuntu-7-60.1611979346.9284.0 [rabbit@ubuntu-7-61.1611979347.10399.0]

![image.png](https://cdn.nlark.com/yuque/0/2021/png/378176/1611995721118-9401bfec-cd31-45c6-9690-e47529dd8c84.png#align=left&display=inline&height=276&margin=%5Bobject%20Object%5D&name=image.png&originHeight=302&originWidth=774&size=23561&status=done&style=stroke&width=708)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/378176/1611995757879-7d3ba5cf-9944-42d3-b376-bf1593686d37.png#align=left&display=inline&height=479&margin=%5Bobject%20Object%5D&name=image.png&originHeight=541&originWidth=719&size=34651&status=done&style=stroke&width=636)
<a name="s1F8l"></a>
#### 3.1.2.2. 配置all模式

设置策略: mirror中所有以 all. 开头的队列将使用该策略

root@ubuntu-7-60:~# rabbitmqctl set_policy —vhost mirror ha-all “^all.“ ‘{“ha-mode”:”all”}’ Setting policy “ha-all” for pattern “^all.“ to “{“ha-mode”:”all”}” with priority “0” for vhost “mirror” …

root@ubuntu-7-60:~# rabbitmqctl list_policies —vhost mirror Listing policies for vhost “mirror” … vhost name pattern apply-to definition priority mirror ha-all ^all. all {“ha-mode”:”all”} 0 mirror ha-exa ^exa. all {“ha-mode”:”exactly”,”ha-params”:2} 0

![image.png](https://cdn.nlark.com/yuque/0/2021/png/378176/1611995880383-05cc9238-7234-4c43-a386-17ef19d3b551.png#align=left&display=inline&height=537&margin=%5Bobject%20Object%5D&name=image.png&originHeight=537&originWidth=760&size=35201&status=done&style=stroke&width=760)
<a name="i4aVp"></a>
#### 3.1.2.3. 配置nodes模式

root@ubuntu-7-60:~# rabbitmqctl set_policy —vhost mirror ha-node “^node.“ ‘{“ha-mode”:”nodes”,”ha-params”:[“rabbit@ubuntu-7-61”,”rabbit@ubuntu-7-62”] }’ Setting policy “ha-node” for pattern “^node.“ to “{“ha-mode”:”nodes”,”ha-params”:[“rabbit@ubuntu-7-61”,”rabbit@ubuntu-7-62”] }” with priority “0” for vhost “mirror” …

root@ubuntu-7-60:~# rabbitmqctl list_policies —vhost mirror Listing policies for vhost “mirror” … vhost name pattern apply-to definition priority mirror ha-node ^node. all {“ha-mode”:”nodes”,”ha-params”:[“rabbit@ubuntu-7-61”,”rabbit@ubuntu-7-62”]} 0 mirror ha-all ^all. all {“ha-mode”:”all”} 0 mirror ha-exa ^exa. all {“ha-mode”:”exactly”,”ha-params”:2} 0 ``` 创建队列的时候,即使选择 ubuntu-7-60 节点也没关系,系统会从61和62节点选择一个作为Master,并迁移到新的master上
image.png