# 消息队列之 rabbit

# 简介

RabbitMQ 是一个开源的消息代理,也称为消息队列,它支持多种消息协议。RabbitMQ 是用 Erlang 语言编写的,具有高并发、高可靠性、易于部署和扩展等特点。它广泛应用于解耦应用组件、异步处理任务、应用程序之间的消息传递等场景。

# RabbitMQ 的主要概念

RabbitMQ 是一个广泛使用的开源消息代理,它基于高级消息队列协议(AMQP)。以下是 RabbitMQ 的一些主要概念:

  1. Broker
    • 消息队列服务器实体。
    • 负责维护和管理消息队列。
  2. Virtual Host (vhost)
    • 虚拟主机提供了逻辑隔离,每个 vhost 都有其自己的队列、交换机和绑定。
    • 一个 RabbitMQ 服务器可以设置多个 vhost,类似于不同的数据库实例。
  3. Exchange
    • 交换机接收生产者发送的消息,根据路由规则将消息路由到一个或多个队列。
    • 常见的交换机类型有 direct(直连)、fanout(广播)、topic(主题)和 headers(头信息)。
  4. Queue
    • 队列是消息的存储实体,消息被发送到队列中并等待消费者获取。
    • 队列可以设置持久化,保证服务器重启后消息不会丢失。
  5. Binding
    • 绑定是交换机和队列之间的关联,通过路由键(routing key)将消息从交换机路由到队列。
    • 一个队列可以绑定到多个交换机。
  6. Routing Key
    • 路由键用于确定消息如何从交换机路由到队列。
    • 路由键在生产者发送消息时指定,并与交换机的类型一起决定消息的路由。
  7. Message
    • 消息是 RabbitMQ 中的基本数据单元,由消息头和消息体组成。
    • 消息体是不透明的,而消息头则包含了元数据。
  8. Producer
    • 生产者是发送消息的客户端应用程序。
    • 生产者创建消息并将其发送到特定的交换机。
  9. Consumer
    • 消费者是接收消息的客户端应用程序。
    • 消费者监听队列并从队列中获取消息进行处理。
  10. Channel
    • 客户端与 RabbitMQ 之间的虚拟连接。
    • 几乎所有的客户端操作都在特定的通道上进行。
  11. Connection
    • 客户端与 RabbitMQ 服务器之间的 TCP 网络连接。
    • 一个连接可以有多个通道。
  12. Acknowledgement (ACK)
    • 消息确认机制,消费者接收到消息后发送一个 ACK 回 RabbitMQ,表明消息已被成功处理。
    • 可以通过手动或自动 ACK 来控制。
  13. Durability
    • 消息或队列的持久化设置,持久化的消息或队列在服务器重启后仍然存在。
  14. Dead Letter Exchange
    • 当消息无法被队列处理时,可以将其发送到一个特殊的交换机,称为死信交换机。
  15. Publisher Confirms
    • 生产者确认机制,确保消息被 RabbitMQ 服务器正确接收。

这些概念构成了 RabbitMQ 的基础架构,使其能够灵活地处理各种消息队列场景。

# 安装 RabbitMQ

# 在 Linux 上安装

  1. 添加 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
  1. 启动 RabbitMQ 服务:
sudo systemctl start rabbitmq-server

# 在 Windows 上安装

  1. 下载安装包:从 RabbitMQ 官网 下载适用于 Windows 的安装包。
  2. 安装 RabbitMQ 服务:运行下载的安装包并按照提示完成安装。
  3. 启动 RabbitMQ 服务:安装完成后,RabbitMQ 将作为 Windows 服务自动启动。

# 在 docker 上安装

在 Docker 中安装 RabbitMQ 并指定密码可以通过以下步骤完成:

  1. 搜索 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]
  1. 拉取 RabbitMQ 镜像: 使用 docker pull 命令拉取带有管理界面的 RabbitMQ 镜像,例如 rabbitmq:management 。如果不指定版本,默认会拉取最新版本。
docker pull rabbitmq:management
  1. 创建并运行 RabbitMQ 容器: 使用 docker run 命令创建并启动一个 RabbitMQ 容器,并通过环境变量 RABBITMQ_DEFAULT_USERRABBITMQ_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 用于设置环境变量,这里设置了默认的用户名和密码。
  1. 确认 RabbitMQ 容器正在运行: 使用 docker ps 命令确认 RabbitMQ 容器是否正在运行。

  2. 访问 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.propertiesapplication.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,可以有效地实现应用解耦、异步处理和流量削峰等场景,提高应用程序的响应速度和可扩展性。

# 参考资料