# 消息队列之 rabbit
# 简介
RabbitMQ 是一个开源的消息代理,也称为消息队列,它支持多种消息协议。RabbitMQ 是用 Erlang 语言编写的,具有高并发、高可靠性、易于部署和扩展等特点。它广泛应用于解耦应用组件、异步处理任务、应用程序之间的消息传递等场景。
# RabbitMQ 的主要概念
RabbitMQ 是一个广泛使用的开源消息代理,它基于高级消息队列协议(AMQP)。以下是 RabbitMQ 的一些主要概念:
- Broker:
- 消息队列服务器实体。
- 负责维护和管理消息队列。
- Virtual Host (vhost):
- 虚拟主机提供了逻辑隔离,每个 vhost 都有其自己的队列、交换机和绑定。
- 一个 RabbitMQ 服务器可以设置多个 vhost,类似于不同的数据库实例。
- Exchange:
- 交换机接收生产者发送的消息,根据路由规则将消息路由到一个或多个队列。
- 常见的交换机类型有 direct(直连)、fanout(广播)、topic(主题)和 headers(头信息)。
- Queue:
- 队列是消息的存储实体,消息被发送到队列中并等待消费者获取。
- 队列可以设置持久化,保证服务器重启后消息不会丢失。
- Binding:
- 绑定是交换机和队列之间的关联,通过路由键(routing key)将消息从交换机路由到队列。
- 一个队列可以绑定到多个交换机。
- Routing Key:
- 路由键用于确定消息如何从交换机路由到队列。
- 路由键在生产者发送消息时指定,并与交换机的类型一起决定消息的路由。
- Message:
- 消息是 RabbitMQ 中的基本数据单元,由消息头和消息体组成。
- 消息体是不透明的,而消息头则包含了元数据。
- Producer:
- 生产者是发送消息的客户端应用程序。
- 生产者创建消息并将其发送到特定的交换机。
- Consumer:
- 消费者是接收消息的客户端应用程序。
- 消费者监听队列并从队列中获取消息进行处理。
- Channel:
- 客户端与 RabbitMQ 之间的虚拟连接。
- 几乎所有的客户端操作都在特定的通道上进行。
- Connection:
- 客户端与 RabbitMQ 服务器之间的 TCP 网络连接。
- 一个连接可以有多个通道。
- Acknowledgement (ACK):
- 消息确认机制,消费者接收到消息后发送一个 ACK 回 RabbitMQ,表明消息已被成功处理。
- 可以通过手动或自动 ACK 来控制。
- Durability:
- 消息或队列的持久化设置,持久化的消息或队列在服务器重启后仍然存在。
- Dead Letter Exchange:
- 当消息无法被队列处理时,可以将其发送到一个特殊的交换机,称为死信交换机。
- Publisher Confirms:
- 生产者确认机制,确保消息被 RabbitMQ 服务器正确接收。
这些概念构成了 RabbitMQ 的基础架构,使其能够灵活地处理各种消息队列场景。
# 安装 RabbitMQ
# 在 Linux 上安装
- 添加 RabbitMQ 软件源(以 Ubuntu 为例):
wget https://dl.bintray.com/rabbitmq/Keys/rabbitmq-release-signing-key.asc | |
sudo apt-key add rabbitmq-release-signing-key.asc | |
sudo apt update | |
sudo apt install rabbitmq-server |
- 启动 RabbitMQ 服务:
sudo systemctl start rabbitmq-server |
# 在 Windows 上安装
- 下载安装包:从 RabbitMQ 官网 下载适用于 Windows 的安装包。
- 安装 RabbitMQ 服务:运行下载的安装包并按照提示完成安装。
- 启动 RabbitMQ 服务:安装完成后,RabbitMQ 将作为 Windows 服务自动启动。
# 在 docker 上安装
在 Docker 中安装 RabbitMQ 并指定密码可以通过以下步骤完成:
- 搜索 RabbitMQ 镜像: 使用
docker search rabbitmq
命令搜索可用的 RabbitMQ 镜像。
[root@localhost ~]# docker search rabbitmq | |
NAME DESCRIPTION STARS OFFICIAL AUTOMATED | |
rabbitmq RabbitMQ is an open source multi-protocol me… 5073 [OK] |
- 拉取 RabbitMQ 镜像: 使用
docker pull
命令拉取带有管理界面的 RabbitMQ 镜像,例如rabbitmq:management
。如果不指定版本,默认会拉取最新版本。
docker pull rabbitmq:management |
- 创建并运行 RabbitMQ 容器: 使用
docker run
命令创建并启动一个 RabbitMQ 容器,并通过环境变量RABBITMQ_DEFAULT_USER
和RABBITMQ_DEFAULT_PASS
来指定默认用户的用户名和密码。
docker run -d \ | |
-p 5672:5672 -p 15672:15672 \ | |
--name my-rabbitmq \ | |
-e RABBITMQ_DEFAULT_USER=myuser \ | |
-e RABBITMQ_DEFAULT_PASS=mypassword \ | |
rabbitmq:management |
在这个命令中:
-d
表示在后台运行容器。-p
用于端口映射,其中5672
是 RabbitMQ 的 AMQP 协议端口,15672
是管理界面的 HTTP 端口。--name
指定容器的名称。-e
用于设置环境变量,这里设置了默认的用户名和密码。
确认 RabbitMQ 容器正在运行: 使用
docker ps
命令确认 RabbitMQ 容器是否正在运行。访问 RabbitMQ 管理界面: 使用浏览器访问
http://<host-ip>:15672
,其中<host-ip>
是运行 Docker 容器的主机 IP 地址。使用步骤 3 中设置的用户名和密码登录管理界面。
# 使用 RabbitMQ
# 管理界面
RabbitMQ 提供了一个易于使用的用户界面,可以通过访问 http://localhost:15672
来管理 RabbitMQ。
# 集成步骤(简单使用)
# 1. 添加依赖
在 pom.xml
文件中添加 Spring Boot 对 RabbitMQ 的支持。
对于 Maven 用户:
<dependencies> | |
<!-- Spring Boot Starter for RabbitMQ --> | |
<dependency> | |
<groupId>org.springframework.boot</groupId> | |
<artifactId>spring-boot-starter-amqp</artifactId> | |
</dependency> | |
</dependencies> |
# 2. 配置 RabbitMQ
在 application.properties
或 application.yml
文件中配置 RabbitMQ 连接信息。
# application.properties | |
spring.rabbitmq.host=localhost | |
spring.rabbitmq.port=5672 | |
spring.rabbitmq.username=guest | |
spring.rabbitmq.password=guest |
或者
# application.yml | |
spring: | |
rabbitmq: | |
host: localhost | |
port: 5672 | |
username: guest | |
password: guest |
# 3. 创建消息生产者
定义一个消息生产者,用于发送消息到 RabbitMQ。
import org.springframework.amqp.rabbit.core.RabbitTemplate; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.stereotype.Component; | |
@Component | |
public class MessageProducer { | |
@Autowired | |
private RabbitTemplate rabbitTemplate; | |
public void send(String routingKey, String message) { | |
rabbitTemplate.convertAndSend("myExchange", routingKey, message); | |
} | |
} |
# 4. 创建消息消费者
定义一个消息消费者,用于接收 RabbitMQ 发送的消息。
import org.springframework.amqp.rabbit.annotation.RabbitListener; | |
import org.springframework.stereotype.Component; | |
@Component | |
public class MessageConsumer { | |
@RabbitListener(queues = "myQueue") | |
public void receive(String message) { | |
System.out.println("Received: " + message); | |
} | |
} |
# 实际使用场景
# 异步处理
在 Web 应用程序中,一些不需要即时返回结果的操作(如发送邮件、生成报告等)可以放入消息队列异步处理。
# 应用解耦
在微服务架构中,服务之间通过消息队列通信,可以降低服务之间的耦合度。
# 流量削峰
在面对突发流量时,可以将请求先写入消息队列,然后由后端服务按顺序处理,避免直接冲击数据库。
# 结论
RabbitMQ 是一个功能强大的消息队列系统,它提供了灵活的消息路由、高可用性配置以及易于使用的管理界面。通过 RabbitMQ,可以有效地实现应用解耦、异步处理和流量削峰等场景,提高应用程序的响应速度和可扩展性。