引言
在分布式系统中,消息队列(Message Queue, 简称 MQ) 是实现异步通信、解耦服务、流量削峰的核心组件。而 RabbitMQ 作为最流行的消息中间件之一,凭借其高可靠性、灵活路由和多协议支持,成为云原生架构中的首选工具。本文将深入解析 MQ 的核心原理,并结合 RabbitMQ 的特点和使用场景,帮助你快速掌握这一关键技术。
一、消息队列(MQ)的核心概念与作用
1. 什么是消息队列?
消息队列是一种异步通信机制,允许生产者(Producer)将消息发送到队列中,消费者(Consumer)从队列中取出并处理消息。消息在队列中暂存,直到被消费者处理完毕。这种机制解决了传统同步通信中的强耦合、性能瓶
2. MQ 的核心组件
- 生产者(Producer):负责创建并发送消息到消息队列。
- 消费者(Consumer):负责从消息队列中获取消息并进行处理。
- 队列(Queue):消息的存储容器,遵循先进先出(FIFO)原则。
- 代理/中间件(Broker):消息队列系统的核心组件,负责消息的存储、路由、转发和持久化。
颈和可靠性问题。
3. MQ 的核心作用
- 异步处理:生产者发送消息后无需等待消费者处理完成即可返回,提高系统响应速度。
- 应用解耦:生产者和消费者通过队列通信,彼此独立,互不影响。
- 流量削峰:在高并发场景下,消息队列可以作为缓冲层,避免系统过载。
- 数据冗余与持久化:支持消息的持久化,即使在系统故障后也不会丢失消息。
- 广播通信:支持一对多(发布/订阅)模式,实现消息的广播。
二、RabbitMQ:消息队列的明星实践(简介)
1. RabbitMQ 是什么?
RabbitMQ 是一个开源的消息中间件,基于 AMQP(Advanced Message Queuing Protocol) 协议实现。它以高可用性、灵活路由和多协议支持著称,广泛应用于微服务架构、分布式系统和实时数据处理场景。
几种常见MQ的对比:

追求可用性:Kafka、 RocketMQ 、RabbitMQ
追求可靠性:RabbitMQ、RocketMQ
追求吞吐能力:RocketMQ、Kafka
追求消息低延迟:RabbitMQ、Kafka
据统计,目前国内消息队列使用最多的还是RabbitMQ,再加上其各方面都比较均衡,稳定性也好
2. RabbitMQ 的核心特点
- 可靠性(Reliability):通过持久化、传输确认、发布确认等机制保证消息不丢失。
- 灵活路由(Flexible Routing):通过 Exchange(交换机)实现复杂的消息路由规则。
- 高可用性(High Availability):支持集群部署和镜像队列,保障服务的高可用。
- 多协议支持:支持 AMQP、STOMP、MQTT 等多种协议。
- 丰富的管理界面:提供 Web 控制台,方便监控和管理消息队列。
- 插件扩展:支持自定义插件,满足个性化需求。
3. RabbitMQ 的核心概念
- Broker(消息代理):RabbitMQ 服务器的实体,负责接收和分发消息。
- Virtual Host(虚拟主机):用于多租户隔离,每个 vhost 是一个独立的命名空间。
- Exchange(交换机) :消息到达的第一站,根据路由规则将消息分发到队列。常见类型包括:
- Direct Exchange:点对点通信。
- Topic Exchange:基于主题的发布-订阅模式。
- Fanout Exchange:广播所有绑定的队列。
- Queue(队列):消息的载体,消费者从队列中取走消息。
- Binding(绑定):Exchange 和 Queue 之间的虚拟连接,定义了路由规则。
- Routing Key(路由键):消息的标识符,Exchange 根据该键决定消息的去向。
三、RabbitMQ、安装教程
在这里我们基于VMware虚拟机的CentOS镜像Linux系统的Docker进行一步安装
在CentOS中部署Docker操作详情: CentOS快速安装Docker指南https://blog.csdn.net/m0_73073987/article/details/149503934?spm=1001.2014.3001.5501
基于Docker来安装RabbitMQ,使用下面的命令即可:
docker run \
-e RABBITMQ_DEFAULT_USER=username \
-e RABBITMQ_DEFAULT_PASS=123456 \
-v mq-plugins:/plugins \
--name mq \
--hostname mq \
-p 15672:15672 \
-p 5672:5672 \
-d \
rabbitmq:3.8-management
可以看到在安装命令中有两个映射的端口:
- 15672:RabbitMQ提供的管理控制台的端口
- 5672:RabbitMQ的消息发送处理接口
安装完成后,我们访问 http://192.168.150.101:15672(ip地址填虚拟机的ip)即可看到管理控制台。首次访问需要登录,默认的用户名和密码在配置文件中已经指定了。
登录后即可看到管理控制台总览页面:

RabbitMQ对应的架构如图:

其中包含几个概念:
- publisher:生产者,也就是发送消息的一方
- consumer:消费者,也就是消费消息的一方
- queue:队列,存储消息。生产者投递的消息会暂存在消息队列中,等待消费者处理
- exchange:交换机,负责消息路由。生产者发送的消息由交换机决定投递到哪个队列。
- virtual host:虚拟主机,起到数据隔离的作用。每个虚拟主机相互独立,有各自的exchange、queue
上述这些东西都可以在RabbitMQ的管理控制台来管理
四、收发消息
4.1交换机
我们打开Exchanges选项卡,可以看到已经存在很多交换机:
我们点击任意交换机,即可进入交换机详情页面。仍然会利用控制台中的publish message 发送一条消息:
这里是由控制台模拟了生产者发送的消息。由于没有消费者存在,最终消息丢失了,这样说明交换机没有存储消息的能力。
注意: 交换机没有存储信息的能力, 只负责将信息转发到对应的队列中
4.2队列
我们打开Queues选项卡,新建一个队列:
命名为hello.queue1:
再以相同的方式,创建一个队列,密码为hello.queue2,最终队列列表如下:

此时,我们再次向amq.fanout交换机发送一条消息。会发现消息依然没有到达队列!!
怎么回事呢?
发送到交换机的消息,只会路由到与其绑定的队列,因此仅仅创建队列是不够的,我们还需要将其与交换机绑定。
4.3绑定关系
点击Exchanges选项卡,点击amq.fanout交换机,进入交换机详情页,然后点击Bindings菜单,在表单中填写要绑定的队列名称:

相同的方式,将hello.queue2也绑定到改交换机。
最终,绑定结果如下:
4.3发送消息
再次回到exchange页面,找到刚刚绑定的amq.fanout,点击进入详情页,再次发送一条消息:

回到Queues页面,可以发现hello.queue中已经有一条消息了:
点击队列名称,进入详情页,查看队列详情,这次我们点击get message:
可以看到消息到达队列了:
这个时候如果有消费者监听了MQ的hello.queue1或hello.queue2队列,自然就能接收到消息了。
5.数据隔离
5.1用户管理
点击Admin选项卡,首先会看到RabbitMQ控制台的用户管理界面:

这里的用户都是RabbitMQ的管理或运维人员。目前只有安装RabbitMQ时添加的itheima这个用户。仔细观察用户表格中的字段,如下:
- Name:itheima,也就是用户名
- Tags:administrator,说明itheima用户是超级管理员,拥有所有权限
- Can access virtual host: /,可以访问的virtual host,这里的/是默认的virtual host
对于小型企业而言,出于成本考虑,我们通常只会搭建一套MQ集群,公司内的多个不同项目同时使用。这个时候为了避免互相干扰, 我们会利用virtual host的隔离特性,将不同项目隔离。一般会做两件事情:
- 给每个项目创建独立的运维账号,将管理权限分离。
- 给每个项目创建不同的virtual host,将每个项目的数据隔离。
比如,我们创建一个新的用户命名为hmall:
你会发现此时hmall用户没有任何virtual host的访问权限:
别急,接下来我们就来授权。
5.2virtual host
我们先退出登录:
切换到刚刚创建的hmall用户登录,然后点击Virtual Hosts菜单,进入virtual host管理页:

可以看到目前只有一个默认的virtual host,名字为 /。
我们可以给用户hmall创建一个单独的virtual host,而不是使用默认的/。
创建完成后如图:
由于我们是登录hmall账户后创建的virtual host,因此回到users菜单,你会发现当前用户已经具备了对/hmall这个virtual host的访问权限了:
此时,点击页面右上角的virtual host下拉菜单,切换virtual host为 /hmall:
然后再次查看queues选项卡,会发现之前的队列已经看不到了:

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