2、RabbitMQ入门:RabbitMQ架构与核心概念、AMQP协议简介、RabbitMQ安装与启动

2.1 为什么选择RabbitMQ?

说实话,消息队列的选择挺多的。Kafka、RocketMQ、Redis Stream,各有各的绝活。但如果你问我,在Node.js项目里做任务调度和异步解耦,我最先想到的还是RabbitMQ。

为什么?因为它足够成熟,而且对开发者友好。我2018年第一次在电商项目里引入RabbitMQ,当时团队里没人用过消息队列。结果呢?三天上手,一周上线。嗯,这就是RabbitMQ的魅力——概念清晰,文档齐全,社区活跃。

你想想看,一个消息队列要能稳定跑在生产环境,还要让团队快速上手,这本身就是个技术活。RabbitMQ做到了。

2.2 RabbitMQ架构与核心概念

先别急着装软件。咱们先把架构理清楚。不然你装好了也不知道怎么用。

2.2.1 整体架构

RabbitMQ的架构,说白了就是三个角色:生产者、代理、消费者。

  • 生产者(Producer):发消息的一方。比如你的订单服务。
  • 代理(Broker):RabbitMQ服务器本身。负责接收、存储、转发消息。
  • 消费者(Consumer):收消息的一方。比如你的邮件通知服务。

但光有这三个还不够。RabbitMQ在中间加了一层抽象——交换机(Exchange)队列(Queue)。生产者不直接发消息到队列,而是发到交换机。交换机根据规则把消息路由到队列。消费者再从队列里取消息。

我个人习惯把这个过程比喻成快递:生产者是寄件人,交换机是分拣中心,队列是快递柜,消费者是收件人。这样一想,是不是清晰多了?

2.2.2 核心概念详解

咱们一个一个来过。这些概念你搞懂了,RabbitMQ就算入门了。

概念 说明 我的一点经验
Message 消息本身。包含消息体和属性。 属性里可以设置优先级、过期时间。我在日志系统里就用过期时间自动清理旧消息。
Producer 消息生产者。负责发布消息。 记得做确认机制。不然消息丢了都不知道。
Consumer 消息消费者。负责处理消息。 一定要处理异常。不然消息会一直重试,把系统拖垮。
Queue 消息队列。存储消息的缓冲区。 队列名建议用点号分隔,比如 order.payment.success
Exchange 交换机。消息路由的核心。 四种类型,后面细说。选错了路由规则会乱套。
Binding 绑定。把交换机和队列连接起来。 绑定的时候可以指定路由键。这个键很重要。
Routing Key 路由键。交换机根据它决定消息去哪。 我见过有人把路由键和队列名搞混,结果消息全跑偏了。
Virtual Host 虚拟主机。隔离不同项目的资源。 每个项目一个vhost,互不干扰。强烈推荐。

2.2.3 交换机类型

交换机有四种类型。我挑最常用的两种重点说。

  • Direct Exchange:直连交换机。路由键精确匹配。比如路由键是 error,只有绑定了 error 的队列才能收到消息。我在订单系统里就用这种,简单粗暴。
  • Topic Exchange:主题交换机。路由键支持通配符。 # 匹配零个或多个单词, * 匹配一个单词。比如 order.# 能匹配 order.payment.successorder.shipped。这个很灵活,我一般在日志收集系统里用。
  • Fanout Exchange:扇形交换机。广播模式。消息发给所有绑定的队列。我用来做配置更新通知。
  • Headers Exchange:头部交换机。根据消息头属性匹配。用得少,了解就行。

重点提醒:Topic Exchange 是最灵活的,也是我项目里用得最多的。如果你不确定选哪种,先从 Topic 开始。

2.3 AMQP协议简介

RabbitMQ 实现了 AMQP 0-9-1 协议。AMQP 全称是 Advanced Message Queuing Protocol,高级消息队列协议。

说白了,它就是一套消息队列的通用规范。就像 HTTP 协议规范了网页访问一样,AMQP 规范了消息的发送、存储、转发。

AMQP 协议有三个核心组件:

  • Exchange:接收生产者消息,按规则路由。
  • Queue:存储消息,等待消费者消费。
  • Binding:定义 Exchange 和 Queue 的关系。

你可能会问:为什么非要搞个协议?直接用 TCP 不行吗?

嗯,这个问题我当初也想过。后来在跨语言项目里,我明白了。AMQP 的好处是:不管你是 Node.js、Python 还是 Java,只要实现了 AMQP 协议,就能互相通信。我之前的项目就是 Node.js 生产消息,Java 消费消息,配合得天衣无缝。

小提示:AMQP 0-9-1 和 AMQP 1.0 是两回事。RabbitMQ 用的是 0-9-1 版本。别搞混了。

2.4 RabbitMQ安装与启动

好了,理论讲完了。咱们动手装一个。

2.4.1 安装方式

我推荐用 Docker 安装。为什么?干净、快速、好卸载。我曾经在 Mac 上直接装,结果卸载的时候一堆残留文件,折腾了半天。

Docker 安装(推荐)

# 拉取镜像
docker pull rabbitmq:3.12-management

# 启动容器
docker run -d \
  --name rabbitmq \
  -p 5672:5672 \
  -p 15672:15672 \
  rabbitmq:3.12-management

这里注意两个端口:

  • 5672:AMQP 协议端口,给程序用的。
  • 15672:管理界面端口,给人类用的。

直接安装(Linux/Mac)

# Ubuntu/Debian
sudo apt-get install rabbitmq-server

# Mac
brew install rabbitmq

我个人习惯用 Docker。你想想看,一行命令就搞定了,还能随时换版本。多省心。

2.4.2 启动与验证

启动之后,先检查一下状态:

# 查看容器状态
docker ps | grep rabbitmq

# 查看 RabbitMQ 状态
docker exec rabbitmq rabbitmqctl status

如果看到 running 字样,说明启动成功了。

然后打开浏览器,访问 http://localhost:15672。默认用户名密码都是 guest

注意:guest 用户只能在 localhost 登录。如果你要远程访问,需要创建新用户。我曾经在生产环境忘了改这个,结果运维同事远程连不上,大半夜打电话给我...

2.4.3 管理界面初探

登录进去之后,你会看到几个关键页面:

  • Overview:概览。显示节点状态、队列数量、消息速率。
  • Connections:连接。查看当前有哪些客户端连着。
  • Channels:通道。每个连接可以开多个通道。
  • Exchanges:交换机。管理所有交换机。
  • Queues:队列。管理所有队列。
  • Admin:管理用户、虚拟主机等。

我建议你先去 Queues 页面看看。创建一个测试队列,再发几条消息试试。亲手操作一遍,比看十遍文档都管用。

2.4.4 常用命令

这几个命令你早晚用得上:

# 查看所有队列
rabbitmqctl list_queues

# 查看所有交换机
rabbitmqctl list_exchanges

# 创建用户
rabbitmqctl add_user myuser mypassword

# 设置用户权限
rabbitmqctl set_permissions -p / myuser ".*" ".*" ".*"

# 创建虚拟主机
rabbitmqctl add_vhost myvhost

小技巧:我习惯把常用命令写成脚本。每次部署新环境,跑一遍脚本就完事了。省得一个个敲。

2.5 避坑指南

最后分享几个我踩过的坑:

  • 端口冲突:5672 端口容易被其他服务占用。启动前先检查一下。
  • 内存限制:RabbitMQ 默认内存上限是 40%。如果消息量大,记得调高。不然会触发流控,消息发不进去。
  • 持久化配置:队列和消息默认不持久化。重启就丢了。生产环境一定要配持久化。
  • 心跳超时:客户端长时间不发送心跳,连接会被断开。我遇到过 Node.js 客户端跑了一晚上,第二天早上发现连不上了。后来把心跳间隔设短一点就好了。

嗯,这一章的内容就到这。RabbitMQ 的架构和核心概念你心里应该有数了。下一章咱们写代码,用 Node.js 连上 RabbitMQ,真正跑起来。