RabbitMQ — 异步调用

RabbitMQ 是一个开源的消息代理中间件,它使用高级消息队列协议(AMQP, Advanced Message Queuing Protocol)来实现不同系统之间的消息传递。它以 Erlang 语言编写,具有高可靠性、灵活性和易于扩展的特点,被广泛应用于异步通信、数据流处理等场景。

官网地址:https://www.rabbitmq.com/

1. RabbitMQ 的核心组件

在 RabbitMQ 中,主要有以下几个核心组件:

  1. Producer(生产者): 负责发送消息的应用程序或系统。生产者将消息发送到指定的交换机。

  2. Exchange(交换机): 接收生产者的消息,并根据路由规则将消息转发到队列。交换机类型决定了消息的路由方式。主要的交换机类型有:

    • Direct Exchange(直连交换机): 精确匹配路由键,将消息发送到指定的队列。

    • Fanout Exchange(扇形交换机): 广播模式,将消息发送到绑定的所有队列。

    • Topic Exchange(主题交换机): 根据通配符匹配路由键,将消息发送到相应的队列。

    • Headers Exchange(头交换机): 根据消息头属性来匹配队列,使用不多。

  3. Queue(队列): 消息的存储区域,消费者从队列中获取消息。消息在队列中以 FIFO(先进先出)方式进行存储。

  4. Binding(绑定): 将交换机与队列连接起来,定义了交换机如何根据路由键将消息路由到队列。

  5. Consumer(消费者): 从队列中接收消息并进行处理的应用程序或服务。

  6. Routing Key(路由键): 生产者发送消息时,指定的一个标签,用于交换机确定将消息转发到哪个队列。

  7. Virtual Host(虚拟主机): 用于多租户隔离的逻辑分区,每个 Virtual Host 可以有自己的交换机、队列、绑定等。

  8. Connection 和 Channel:

    • Connection(连接): 指的是应用程序与 RabbitMQ Broker 的 TCP 连接。

    • Channel(信道): 多个 Channel 可以复用同一个 Connection。通常建议每个线程使用一个独立的 Channel。

2. RabbitMQ 的工作流程

RabbitMQ 的消息流大致如下:

  1. 生产者 将消息发送到交换机(Exchange)

  2. 交换机 根据消息的路由键和绑定规则,将消息分配到相应的队列(Queue)

  3. 消费者从队列中获取消息并处理。

  4. 确认机制(ACK): 消费者处理完消息后,发送确认。RabbitMQ 将确认的消息从队列中删除,确保消息不被重复消费。

3. 服务部署

基于Docker来安装RabbitMQ,使用下面的命令即可:

复制代码
docker run \
 -e RABBITMQ_DEFAULT_USER=cyt\
 -e RABBITMQ_DEFAULT_PASS=123321 \
 -v mq-plugins:/plugins \
 --name mq \
 --hostname mq \
 -p 15672:15672 \
 -p 5672:5672 \
 --network cyt-net\
 -d \
 rabbitmq:3.8-management

可以看到在安装命令中有两个映射的端口:

  • 15672:RabbitMQ提供的管理控制台的端口

  • 5672:RabbitMQ的消息发送处理接口

安装完成后,我们访问 http://ip:15672即可看到管理控制台。首次访问需要登录,默认的用户名和密码在配置文件中已经指定了。

4. 收发消息

4.1 交换机

管理控制台主页,打开Exchanges选项卡,可以看到已经存在很多交换机

点击任意交换机,即可进入交换机详情页面。

利用控制台中的publish message 发送一条消息

这里是由控制台模拟了生产者发送的消息。由于没有消费者存在,最终消息丢失了,这样说明交换机没有存储消息的能力。

4.2 队列

打开Queues选项卡,新建一个队列

此时,我们再次向amq.fanout交换机发送一条消息。会发现消息依然没有到达队列!!

怎么回事呢?

发送到交换机的消息,只会路由到与其绑定的队列,因此仅仅创建队列是不够的,我们还需要将其与交换机绑定。

4.3 绑定关系

点击Exchanges选项卡,点击amq.fanout交换机,进入交换机详情页,然后点击Bindings菜单,在表单中填写要绑定的队列名称

4.4 发送消息

再次回到exchange页面,找到刚刚绑定的amq.fanout,点击进入详情页,再次发送一条消息。

回到Queues页面,可以发现被绑定的队列中已经有一条消息了。

这个时候如果有消费者监听了MQ的队列,自然就能接收到消息了。

5. 数据隔离

5.1 用户管理

点击Admin选项卡,首先会看到RabbitMQ控制台的用户管理界面:

这里的用户都是RabbitMQ的管理或运维人员。目前只有安装RabbitMQ时添加的cyt这个用户。仔细观察用户表格中的字段,如下:

  • Namecyt,也就是用户名

  • Tagsadministrator,说明cyt用户是超级管理员,拥有所有权限

  • Can access virtual host/,可以访问的virtual host,这里的/是默认的virtual host

对于小型企业而言,出于成本考虑,通常只会搭建一套MQ集群,公司内的多个不同项目同时使用。这个时候为了避免互相干扰, 我们会利用virtual host的隔离特性,将不同项目隔离。一般会做两件事情:

  • 给每个项目创建独立的运维账号,将管理权限分离。

  • 给每个项目创建不同的virtual host,将每个项目的数据隔离。

比如,我们创建一个新的用户,命名为cyt123,发现此时cyt123用户没有任何virtual host的访问权限,下来需要进行授权。

5.2 virtual host

切换到刚刚创建的cyt123用户登录,然后点击Virtual Hosts菜单,进入virtual host管理页

可以看到目前只有一个默认的virtual host,名字为 /

可以在该用户下创建一个单独的virtual host,而不是使用默认的/

由于我们是登录cyt123账户后创建的virtual host,因此回到admin菜单,你会发现当前用户已经具备了对新建的这个virtual host的访问权限了。

此时,点击页面右上角的virtual host下拉菜单,切换virtual host为 刚刚创建的,然后就可以对这个virtual host下的交换机和队列进行操作。

这就是基于virtual host 的隔离效果。

相关推荐
初次攀爬者1 天前
ZooKeeper 实现分布式锁的两种方式
分布式·后端·zookeeper
让我上个超影吧2 天前
消息队列——RabbitMQ(高级)
java·rabbitmq
塔中妖2 天前
Windows 安装 RabbitMQ 详细教程(含 Erlang 环境配置)
windows·rabbitmq·erlang
断手当码农2 天前
Redis 实现分布式锁的三种方式
数据库·redis·分布式
初次攀爬者2 天前
Redis分布式锁实现的三种方式-基于setnx,lua脚本和Redisson
redis·分布式·后端
业精于勤_荒于稀2 天前
物流订单系统99.99%可用性全链路容灾体系落地操作手册
分布式
Ronin3052 天前
信道管理模块和异步线程模块
开发语言·c++·rabbitmq·异步线程·信道管理
Asher05092 天前
Hadoop核心技术与实战指南
大数据·hadoop·分布式
elseif1232 天前
循环队列(详细)GESP六级
数据结构·c++·队列·循环队列
凉凉的知识库2 天前
Go中的零值与空值,你搞懂了么?
分布式·面试·go