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.success和order.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,真正跑起来。