消息队列

1 消息队列通俗解释

1.1 什么是消息队列

消息队列不知道大家看到这个词的时候,会不会觉得它是一个比较高端的技术,反正我第一次见到的时候,觉得蛮牛逼的。

消息队列,一般我们会简称它为MQ(Message Queue)

我们先不管消息(Message)这个词,来看看队列(Queue)。

队列是一种先进先出的数据结构。

image-20210802151441672.png

那么为什么需要消息队列这种中间件呢?其实我们可以简单理解为:把要传输的数据放在队列中。

  1. PS:
  2. 把数据放到消息队列叫做生产者
  3. 从消息队列里边取数据叫做消费者

2 为什么要用消息队列呢?

为什么需要消息队列呢?消息队列给我们带来了什么好处呢?我们看看以下场景:

消息队列与微服务 - 图2

消息队列在实际应用中包括如下四个场景:

1、 应用耦合:

多应用间通过消息队列对同一消息进行处理,避免调用接口失败导致整个过程失败;

2、异步处理:

多应用对消息队列中同一消息进行处理,应用间并发处理消息,相比串行处理,减少处理时间;

3、 限流削峰:

广泛应用于秒杀或抢购活动中,避免流量过大导致应用系统挂掉的情况;

4、消息驱动的系统:

系统分为消息队列、消息生产者、消息消费者,生产者负责产生消息,消费者(可能有多个)负责对消息进行处理

下面详细介绍上述四个场景以及消息队列如何在上述四个场景中使用

异步处理:

具体场景:用户为了使用某个应用,进行注册,系统需要发送注册邮件并验证短信。对这两个操作的处理方式有两种:串行及并行。

  1. 串行方式: 新注册信息生成后 , 先发送注册邮件, 再发送验证短信。注意 : 在这种方式下,需要最终发送验证短信后再返回给客户端

消息队列与微服务 - 图3

  1. 并行处理:新注册信息写入后,由发短信和发邮件并行处理。注意: 在这种方式下,发短信和发邮件 需处理完成后再返回给客户端

消息队列与微服务 - 图4

假设以上三个子系统处理的时间均为 50ms ,且不考虑网络延迟,则总的处理时间:

串行: 50+50+50=150ms

并行: 50+50 = 100ms

如果引入消息队列 , 在来看整体的执行效率 :

在写入消息队列后立即返回成功给客户端,则总的响应时间依赖于写入消息队列的时间,而写入消息队列的时间本身是可以很快的,基本可以忽略不计,因此总的处理时间相比串行提高了2倍,相比并行提高了一倍;

应用耦合

具体场景:

用户使用 QQ 相册上传一张图片,人脸识别系统会对该图片进行人脸识别,一般的做法是,服务器接收到图片后,图片上传系统立即调用人脸识别系统,调用完成后再返回成功,如下图所示: 如果引入消息队列 , 在来看整体的执行效率

消息队列与微服务 - 图5

该方法有如下缺点:

  • 人脸识别系统被调失败,导致图片上传失败;
  • 延迟高,需要人脸识别系统处理完成后,再返回给客户端,即使用户并不需要立即知道结果;
  • 图片上传系统与人脸识别系统之间互相调用,需要做耦合;

若使用消息队列:

消息队列与微服务 - 图6

此时图片上传系统并不需要关心人脸识别系统是否对这些图片信息的处理、以及何时对这些图片信息进行处理。

事实上,由于用户并不需要立即知道人脸识别结果,人脸识别系统可以选择不同的调度策略,按照闲时、忙时、正常时 间,对队列中的图片信息进行处理。

限流削峰

具体场景:

购物网站开展秒杀活动,一般由于瞬时访问量过大,服务器接收过大,会导致流量暴增,相关系统无法处理请求甚至崩溃。而加入消息队列后,系统可以从消息队列中取数据,相当于消息队列做了一次缓冲。

消息队列与微服务 - 图7

该方法有如下优点:

  • 请求先入消息队列,而不是由业务处理系统直接处理,做了一次缓冲 , 极大地减少了业务处理系统的压力;
  • 队列长度可以做限制,事实上,秒杀时,后入队列的用户无法秒杀到商品,这些请求可以直接被抛弃,返回活动已结束或商品已售完信息;

消息驱动系统

具体场景:

用户新上传了一批照片, 人脸识别系统需要对这个用户的所有照片进行聚类,聚类完成后由对账系统重新生成用 户的人脸索引( 加快查询 ) 。这三个子系统间由消息队列连接起来,前一个阶段的处理结果放入队列中,后一个阶段从队列中获取消息继续处理。

消息队列与微服务 - 图8

该方法有如下优点:

  • 避免了直接调用下一个系统导致当前系统失败;
  • 每个子系统对于消息的处理方式可以更为灵活,可以选择收到消息时就处理,可以选择定时处理,也可以划分时间 段按不同处理速度处理;

3 消息队列的两种方式

3.1 点对点模式

点对点模式下包括三个角色

  • 消息队列
  • 发送者 (生产者)
  • 接收者(消费者)

消息队列与微服务 - 图9

消息发送者生产消息发送到 queue 中,然后消息接收者从 queue 中取出并且消费消息。消息被消费以后, queue 中不再有存储,所以消息接收者不可能消费到已经被消费的消息。

点对点模式特点:

每个消息只有一个接收者(Consumer)(即一旦被消费,消息就不再在消息队列中);

发送者和接收者间没有依赖性,发送者发送消息之后,不管有没有接收者在运行,都不会影响到发送者下次发送消息;

接收者在成功接收消息之后需向队列应答成功,以便消息队列删除当前接收的消息;

3.2 发布订阅模式

发布/订阅模式下包括三个角色:

  • 角色主题(Topic)
  • 发布者(Publisher)
  • 订阅者(Subscriber)

消息队列与微服务 - 图10

发布者将消息发送到Topic,系统将这些消息传递给多个订阅者。

发布/订阅模式特点:

  • 每个消息可以有多个订阅者
  • 发布者和订阅者之间有时间上的依赖性。针对某个主题(Topic)的订阅者,它必须创建一个订阅者之后,才能消费发布者的消息。
  • 为了消费消息,订阅者需要提前订阅该角色主题,并保持在线运行。

4 RabbitMQ

4.1 RabbitMQ简介

RabbitMQ是一个由Erlang语言开发的AMQP的开源实现。

AMQP:Advanced Message Queue,高级消息队列协议。它是应用层协议的一个开放标准,为面向消息的中间件设计,基于此协议的客户端与消息中间件可传递消息,并不受产品、开发语言等条件的限制。

4.2 RabbitMQ特点

  • 开源、性能优秀,稳定性保障
  • 提供可靠性消息投递模式、返回模式
  • 与Spring AMQP完美整合,API丰富
  • 集群模式丰富,表达式配置,HA模式,镜像队列模型
  • 保证数据不丢失的前提做到高可靠性、可用性

4.3 RabbitMQ的应用场景

  • 异步处理。把消息放入消息中间件中,等到需要的时候再去处理。
  • 流量削峰。例如秒杀活动,在短时间内访问量急剧增加,使用消息队列,当消息队列满了就拒绝响应,跳转到错误页面,这样就可以使得系统不会因为超负载而崩溃。
  • 日志处理
  • 应用解耦。假设某个服务A需要给许多个服务(B、C、D)发送消息,当某个服务(例如B)不需要发送消息了,服务A需要改代码再次部署;当新加入一个服务(服务E)需要服务A的消息的时候,也需要改代码重新部署;另外服务A也要考虑其他服务挂掉,没有收到消息怎么办?要不要重新发送呢?是不是很麻烦,使用MQ发布订阅模式,服务A只生产消息发送到MQ,B、C、D从MQ中读取消息,需要A的消息就订阅,不需要了就取消订阅,服务A不再操心其他的事情,使用这种方式可以降低服务或者系统之间的耦合。

4.4 RabbitMQ中的概念模型

所有 MQ 产品从模型抽象上来说都是一样的过程:

消费者(consumer)订阅某个队列。生产者(producer)创建消息,然后发布到队列(queue)中,最后将消息发送到监听的消费者。

image-20210807171410769.png

4.5 RabbitMQ基本概念

上面只是最简单抽象的描述,具体到 RabbitMQ 则有更详细的概念需要解释。上面介绍过 RabbitMQ 是 AMQP 协议的一个开源实现,所以其内部实际上也是 AMQP 中的基本概念:

image-20210807171508895.png

  • Message:消息,消息是不具名的,它由消息头和消息体组成。消息体是不透明的,而消息头则由一系列的可选属性组成,这些属性包括routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(指出该消息可能需要持久性存储)等。
  • Publisher:消息的生产者,也是一个向交换器发布消息的客户端应用程序。
  • Exchange:交换器,用来接收生产者发送的消息并将这些消息路由给服务器中的队列。
  • Binding:绑定,用于消息队列和交换器之间的关联。一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则,所以可以将交换器理解成一个由绑定构成的路由表。
  • Queue:消息队列,用来保存消息直到发送给消费者。它是消息的容器,也是消息的终点。一个消息可投入一个或多个队列。消息一直在队列里面,等待消费者连接到这个队列将其取走。
  • Connection:网络连接,比如一个TCP连接。
  • Channel:信道,多路复用连接中的一条独立的双向数据流通道。信道是建立在真实的TCP连接内地虚拟连接,AMQP 命令都是通过信道发出去的,不管是发布消息、订阅队列还是接收消息,这些动作都是通过信道完成。因为对于操作系统来说建立和销毁 TCP 都是非常昂贵的开销,所以引入了信道的概念,以复用一条 TCP 连接。
  • Consumer:消息的消费者,表示一个从消息队列中取得消息的客户端应用程序。
  • Virtual Host:虚拟主机,表示一批交换器、消息队列和相关对象。虚拟主机是共享相同的身份认证和加密环境的独立服务器域。每个 vhost 本质上就是一个 mini 版的 RabbitMQ 服务器,拥有自己的队列、交换器、绑定和权限机制。vhost 是 AMQP 概念的基础,必须在连接时指定,RabbitMQ 默认的 vhost。
  • Broker:表示消息队列服务器实体。

4.6 安装单机版RabbitMQ

进入官网首页

13118451-7c3873d5e3ad0742.png

Centos7系统需要rpm安装找到如下链接,Rabbit依赖erlang在安装之前一定要确保erlang环境存在而且版本一定要对应

13118451-d6dc1de74f124567.png

点开erlang版本,您将看到rabbit与erlang的对应表

13118451-71cf54ba16233917.png

从图里可以看得出来,这其实就是rabbitmq和erlang的版本对应关系,要安装rabbitmq,必须得有erlang的环境,就跟java需要JVM一个道理。

好了,我们正式开始部署了

  1. #1、编辑repo文件
  2. [root@mq-67 ~]# cat /etc/yum.repos.d/rabbitmq.repo
  3. [rabbitmq_erlang]
  4. name=rabbitmq_erlang
  5. baseurl=https://packagecloud.io/rabbitmq/erlang/el/7/$basearch
  6. repo_gpgcheck=1
  7. gpgcheck=1
  8. enabled=1
  9. # PackageCloud's repository key and RabbitMQ package signing key
  10. gpgkey=https://packagecloud.io/rabbitmq/erlang/gpgkey
  11. https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc
  12. sslverify=1
  13. sslcacert=/etc/pki/tls/certs/ca-bundle.crt
  14. metadata_expire=300
  15. [rabbitmq_erlang-source]
  16. name=rabbitmq_erlang-source
  17. baseurl=https://packagecloud.io/rabbitmq/erlang/el/7/SRPMS
  18. repo_gpgcheck=1
  19. gpgcheck=0
  20. enabled=1
  21. gpgkey=https://packagecloud.io/rabbitmq/erlang/gpgkey
  22. sslverify=1
  23. sslcacert=/etc/pki/tls/certs/ca-bundle.crt
  24. metadata_expire=300
  25. ##
  26. ## RabbitMQ server
  27. ##
  28. [rabbitmq_server]
  29. name=rabbitmq_server
  30. baseurl=https://packagecloud.io/rabbitmq/rabbitmq-server/el/7/$basearch
  31. repo_gpgcheck=1
  32. gpgcheck=1
  33. enabled=1
  34. # PackageCloud's repository key and RabbitMQ package signing key
  35. gpgkey=https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey
  36. https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc
  37. sslverify=1
  38. sslcacert=/etc/pki/tls/certs/ca-bundle.crt
  39. metadata_expire=300
  40. [rabbitmq_server-source]
  41. name=rabbitmq_server-source
  42. baseurl=https://packagecloud.io/rabbitmq/rabbitmq-server/el/7/SRPMS
  43. repo_gpgcheck=1
  44. gpgcheck=0
  45. enabled=1
  46. gpgkey=https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey
  47. sslverify=1
  48. sslcacert=/etc/pki/tls/certs/ca-bundle.crt
  49. metadata_expire=300
  50. #2、配置主机名解析
  51. [root@mq-67 ~]# hostnamectl set-hostname mq-67
  52. [root@mq-67 ~]# vim /etc/hosts
  53. 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
  54. ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
  55. 10.0.0.67 mq-67 mq
  56. #3、安装RabbitMQ
  57. [root@mq-67 ~]# yum install socat logrotate -y
  58. [root@mq-67 ~]# yum install erlang rabbitmq-server -y
  59. #4、启动RabbitMQ
  60. [root@mq-67 ~]# systemctl enable rabbitmq-server
  61. [root@mq-67 ~]# systemctl start rabbitmq-server

4.6.1 RabbitMQ插件管理

开启web界面管理插件:

  1. [root@mq-67 ~]# rabbitmq-plugins enable rabbitmq_management
  2. Enabling plugins on node rabbit@mq-67:
  3. rabbitmq_management
  4. The following plugins have been configured:
  5. .....
  6. started 3 plugins.

4.6.2 登录web管理界面

RabbitMQ从3.3.0开始禁止使用guest权限通过除localhost外的访问,直接访问就会提示您无法访问,必须使用localhost才能访问。所以我们需要配置一下才行,配置过程如下:

  1. #1、新增一个管理员用户
  2. [root@mq-67 ~]# rabbitmqctl add_user xujun 123456
  3. Adding user "xujun" ...
  4. Done. Don't forget to grant the user permissions to some virtual hosts! See 'rabbitmqctl help set_permissions' to learn more.
  5. #2、给xujun用户提升为administrator
  6. [root@mq-67 ~]# rabbitmqctl set_user_tags xujun administrator
  7. Setting tags for user "xujun" to [administrator] ...

然后接下去就可以使用xujun/123456来登录页面了:

image-20210807232433575.png

4.7 RabbitMQ二进制部署

  1. 去华为镜像源下载rbbitmq的二进制包
  2. https://repo.huaweicloud.com/
  3. #1、配置主机名解析
  4. [root@mq-69 ~]# hostnamectl set-hostname mq-67
  5. [root@mq-69 ~]# vim /etc/hosts
  6. 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
  7. ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
  8. 10.0.0.69 mq-69 mq
  9. #2、安装erlang语言和依赖包
  10. [root@mq-69 ~]# yum install socat logrotate -y
  11. [root@mq-69 ~]# yum install erlang -y
  12. #3、下载二进制包,并解压
  13. [root@mq-69 src]# wget https://repo.huaweicloud.com/rabbitmq-server/v3.9.0/rabbitmq-server-generic-unix-3.9.0.tar.xz
  14. [root@mq-69 src]# tar xf rabbitmq-server-generic-unix-3.9.0.tar.xz
  15. #4、给目录做软链接,并授权
  16. [root@mq-69 src]# mv rabbitmq_server-3.9.0/ ../
  17. [root@mq-69 local]# ln -s rabbitmq_server-3.9.0/ rabbitmq_server
  18. [root@mq-69 local]# chown -R rabbitmq:rabbitmq rabbitmq_server-3.9.0/
  19. #5、添加环境变量
  20. [root@mq-69 rabbitmq_server]# vim /etc/profile
  21. export PATH=$PATH:/usr/local/rabbitmq_server/sbin
  22. [root@mq-69 rabbitmq_server]# source /etc/profile
  23. #6、添加rabbitmq用户
  24. [root@mq-69 ~]# useradd rabbitmq -s /sbin/nologin -M
  25. #7、以systemd启动程序
  26. [root@mq-69 rabbitmq_server]# cat /usr/lib/systemd/system/rabbitmq-server.service
  27. [Unit]
  28. Description=RabbitMQ broker
  29. After=syslog.target network.target
  30. [Service]
  31. Type=notify
  32. User=rabbitmq
  33. Group=rabbitmq
  34. UMask=0027
  35. NotifyAccess=all
  36. TimeoutStartSec=600
  37. # To override LimitNOFILE, create the following file:
  38. #
  39. # /etc/systemd/system/rabbitmq-server.service.d/limits.conf
  40. #
  41. # with the following content:
  42. #
  43. # [Service]
  44. # LimitNOFILE=65536
  45. LimitNOFILE=32768
  46. # Note: systemd on CentOS 7 complains about in-line comments,
  47. # so only append them here
  48. #
  49. # Restart:
  50. # The following setting will automatically restart RabbitMQ
  51. # in the event of a failure. systemd service restarts are not a
  52. # replacement for service monitoring. Please see
  53. # https://www.rabbitmq.com/monitoring.html
  54. Restart=on-failure
  55. RestartSec=10
  56. WorkingDirectory=/usr/local/rabbitmq_server
  57. ExecStart=/usr/local/rabbitmq_server/sbin/rabbitmq-server
  58. ExecStop=/usr/local/rabbitmq_server/sbin/rabbitmqctl shutdown
  59. # See rabbitmq/rabbitmq-server-release#51
  60. SuccessExitStatus=69
  61. [Install]
  62. WantedBy=multi-user.target
  63. #8、启动rabbitmq
  64. [root@mq-69 rabbitmq]# systemctl daemon-reload
  65. [root@mq-69 rabbitmq]# systemctl restart rabbitmq-server

4.8 RabbitMQ集群部署

4.8.1RabbitMQ集群分为二种方式

  • 普通模式:创建好RabbitMQ集群之后的默认模式。
    1. 普通集群模式:queue创建之后,如果没有其他policy,消息实体只存在于其中一个节点,AB两个RabbitMQ节点仅有相同的元数据,即队列结构,但队列的数据仅保存有一份,即创建该队列的RabbitMQ节点(A节点),当消息进入A节点的Queue中后,consumerB节点拉取时,RabbitMQ会临时在AB间进行消息传输,把A中的消息实体取出并经过B发送给Consumer,所以Consumer可以连接每一个节点,从中取消息,该模式存在一个问题就是当A节点故障后,B节点无法取到A节点中还未消费的消息实体
  • 镜像模式:把需要的队列做成镜像队列。
    1. 镜像集群模式:把需要的队列做成镜像队列,存在于多个节点,属于RabbitMQHA方案(镜像模式是在普通模式的基础上,增加一些镜像策略)。该模式解决了普通模式中的数据丢失问题,其实质和普通模式不同之处在于,消息实体会主动在镜像节点间同步,而不是Consumer取数据时临时拉取,该模式带来的副作用也很明显,除了降低系统性能外,如果镜像队列数量过多,加之大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗掉,所以在对可靠性要求较高的场合中适用,一个队列想做成镜像队列,需要先设置policy,然后客户端创建队列的时候,RabbitMQ集群根据“队列名称”自动设置是普通模式或镜像队列。

4.8.2 集群中有两种节点类型

  • 内存节点:只将数据保存到内存中。
  • 磁盘节点:保存数据到内存和磁盘。

内存节点虽然不写入磁盘,但是它执行效率要比磁盘节点要好,集群中,只需要一个磁盘节点来保存数据就足够了。如果集群中只有内存节点,那么不能全部停止它们,否则所有数据消息在服务器全部停机之后都会丢失。

4.8.3 部署RabbitMQ集群

主机名 IP地址 备注
mq-67 10.0.0.67 内存节点
mq-68 10.0.0.68 内存节点
mq-69 10.0.0.69 磁盘节点
  1. #1、三台机器配置域名解析
  2. [root@mq-69 ~]# vim /etc/hosts
  3. 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
  4. ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
  5. 10.0.0.67 mq-67
  6. 10.0.0.68 mq-68
  7. 10.0.0.69 mq-69
  8. #2、各服务器安装RabbitMQ
  9. [root@mq-67 ~]# cat /etc/yum.repos.d/rabbitmq.repo
  10. [rabbitmq_erlang]
  11. name=rabbitmq_erlang
  12. baseurl=https://packagecloud.io/rabbitmq/erlang/el/7/$basearch
  13. repo_gpgcheck=1
  14. gpgcheck=1
  15. enabled=1
  16. # PackageCloud's repository key and RabbitMQ package signing key
  17. gpgkey=https://packagecloud.io/rabbitmq/erlang/gpgkey
  18. https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc
  19. sslverify=1
  20. sslcacert=/etc/pki/tls/certs/ca-bundle.crt
  21. metadata_expire=300
  22. [rabbitmq_erlang-source]
  23. name=rabbitmq_erlang-source
  24. baseurl=https://packagecloud.io/rabbitmq/erlang/el/7/SRPMS
  25. repo_gpgcheck=1
  26. gpgcheck=0
  27. enabled=1
  28. gpgkey=https://packagecloud.io/rabbitmq/erlang/gpgkey
  29. sslverify=1
  30. sslcacert=/etc/pki/tls/certs/ca-bundle.crt
  31. metadata_expire=300
  32. ##
  33. ## RabbitMQ server
  34. ##
  35. [rabbitmq_server]
  36. name=rabbitmq_server
  37. baseurl=https://packagecloud.io/rabbitmq/rabbitmq-server/el/7/$basearch
  38. repo_gpgcheck=1
  39. gpgcheck=1
  40. enabled=1
  41. # PackageCloud's repository key and RabbitMQ package signing key
  42. gpgkey=https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey
  43. https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc
  44. sslverify=1
  45. sslcacert=/etc/pki/tls/certs/ca-bundle.crt
  46. metadata_expire=300
  47. [rabbitmq_server-source]
  48. name=rabbitmq_server-source
  49. baseurl=https://packagecloud.io/rabbitmq/rabbitmq-server/el/7/SRPMS
  50. repo_gpgcheck=1
  51. gpgcheck=0
  52. enabled=1
  53. gpgkey=https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey
  54. sslverify=1
  55. sslcacert=/etc/pki/tls/certs/ca-bundle.crt
  56. metadata_expire=300
  57. #2.1、配置主机名解析
  58. [root@mq-67 ~]# hostnamectl set-hostname mq-67
  59. [root@mq-67 ~]# vim /etc/hosts
  60. 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
  61. ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
  62. 10.0.0.67 mq-67 mq
  63. #2.2、安装RabbitMQ
  64. [root@mq-67 ~]# yum install socat logrotate -y
  65. [root@mq-67 ~]# yum install erlang rabbitmq-server -y
  66. #2.3、启动RabbitMQ
  67. [root@mq-67 ~]# systemctl enable rabbitmq-server
  68. [root@mq-67 ~]# systemctl start rabbitmq-server
  69. #3、创建RabbitMQ集群
  70. RabbitMQ的集群是依赖于erlang的集群来工作的,所以必须先构建起erlang的集群环境,而Erlang的集群中各节点是通过一个magic cookie来实现的,这个cookie存放在/var/lib/rabbitmq/.erlang.cookie中,文件是400的权限,所以必须保证各节点cookie保持一致,否则节点之间就无法通信。
  71. #3.1、关闭RabbitMQ
  72. [root@mq-68 ~]# systemctl stop rabbitmq-server
  73. [root@mq-69 ~]# systemctl stop rabbitmq-server
  74. #3.2、从mq-67同步.erlang.cookie至其他两台服务器
  75. [root@mq-67 ~]# scp -rp /var/lib/rabbitmq/.erlang.cookie root@10.0.0.68:/var/lib/rabbitmq/.erlang.cookie
  76. [root@mq-67 ~]# scp -rp /var/lib/rabbitmq/.erlang.cookie root@10.0.0.69:/var/lib/rabbitmq/.erlang.cookie
  77. #3.3、启动RabbitMQ
  78. [root@mq-68 ~]# systemctl start rabbitmq-server
  79. [root@mq-69 ~]# systemctl start rabbitmq-server
  80. #3.4、在67创建MQ集群
  81. [root@mq-67 ~]# rabbitmqctl stop_app #停止app服务
  82. [root@mq-67 ~]# rabbitmqctl reset #清空元数据
  83. mq-67添加到集群当中,并成为内存节点,不加--ram默认是磁盘节点
  84. [root@mq-67 ~]# rabbitmqctl join_cluster rabbit@mq-69 --ram
  85. [root@mq-67 ~]# rabbitmqctl start_app #启动app服务
  86. #3.5、在68创建MQ集群
  87. [root@mq-68 ~]# rabbitmqctl stop_app #停止app服务
  88. [root@mq-68 ~]# rabbitmqctl reset #清空元数据
  89. mq-68添加到集群当中,并成为内存节点,不加--ram默认是磁盘节点
  90. [root@mq-68 ~]# rabbitmqctl join_cluster rabbit@mq-69 --ram
  91. [root@mq-68 ~]# rabbitmqctl start_app #启动app服务
  92. #3.6、将集群设置为镜像模式
  93. 只需要在任意一个节点上执行以下命令即可:
  94. [root@mq-68 ~]# rabbitmqctl set_policy ha-all "#" '{"ha-mode":"all"}'
  95. #3.7、验证当前集群
  96. [root@mq-68 ~]# rabbitmqctl cluster_status
  97. Cluster status of node rabbit@mq-68 ...
  98. Basics
  99. Cluster name: rabbit@mq-68
  100. Disk Nodes
  101. rabbit@mq-69
  102. RAM Nodes
  103. rabbit@mq-67
  104. rabbit@mq-68
  105. Running Nodes
  106. rabbit@mq-67
  107. rabbit@mq-68
  108. rabbit@mq-69
  109. Versions
  110. rabbit@mq-67: RabbitMQ 3.9.1 on Erlang 23.3.4.5
  111. rabbit@mq-68: RabbitMQ 3.9.1 on Erlang 23.3.4.5
  112. rabbit@mq-69: RabbitMQ 3.9.1 on Erlang 23.3.4.5
  113. Maintenance status
  114. Node: rabbit@mq-67, status: not under maintenance
  115. Node: rabbit@mq-68, status: not under maintenance
  116. Node: rabbit@mq-69, status: not under maintenance
  117. Alarms
  118. (none)
  119. Network Partitions
  120. (none)
  121. Listeners
  122. Node: rabbit@mq-67, interface: [::], port: 15672, protocol: http, purpose: HTTP API
  123. Node: rabbit@mq-67, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
  124. Node: rabbit@mq-67, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
  125. Node: rabbit@mq-68, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
  126. Node: rabbit@mq-68, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
  127. Node: rabbit@mq-69, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
  128. Node: rabbit@mq-69, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
  129. Feature flags
  130. Flag: drop_unroutable_metric, state: enabled
  131. Flag: empty_basic_get_metric, state: enabled
  132. Flag: implicit_default_bindings, state: enabled
  133. Flag: maintenance_mode_status, state: enabled
  134. Flag: quorum_queue, state: enabled
  135. Flag: stream_queue, state: enabled
  136. Flag: user_limits, state: enabled
  137. Flag: virtual_host_metadata, state: enabled
  138. #3.8、web界面验证集群状态
  139. #3.8.1、所有服务器开启插件
  140. [root@mq-68 ~]# rabbitmq-plugins enable rabbitmq_management
  141. [root@mq-68 ~]# rabbitmqctl add_user xujun 123456
  142. [root@mq-68 ~]# rabbitmqctl set_user_tags xujun administrator
  143. [root@mq-69 ~]# rabbitmq-plugins enable rabbitmq_management
  144. [root@mq-69 ~]# rabbitmqctl add_user xujun 123456
  145. [root@mq-69 ~]# rabbitmqctl set_user_tags xujun administrator
  146. #3.8.2、web界面验证集群状态

image-20210808151235657.png

4.9 RabbitMQ常用命令

  1. #创建vhost
  2. [root@mq-69 rabbitmq_server]# rabbitmqctl add_vhost xujun
  3. #列出所有vhost
  4. [root@mq-69 rabbitmq_server]# rabbitmqctl list_vhosts
  5. #列出所有队列
  6. [root@mq-69 rabbitmq_server]# rabbitmqctl list_queues
  7. #删除指定vhost
  8. [root@mq-69 rabbitmq_server]# rabbitmqctl delete_vhost xujun
  9. #添加账户jack 密码为123456
  10. [root@mq-69 rabbitmq_server]# rabbitmqctl add_user jack 123456
  11. #更改用户密码
  12. [root@mq-69 rabbitmq_server]# rabbitmqctl change_password jack 123456789
  13. #设置jack用户对xujun的vhost有读写权限,三个点为配置正则、读和写
  14. [root@mq-69 rabbitmq_server]# rabbitmqctl set_permissions -p xujun jack ".*" ".*" ".*