使用 Spring AMQP 进行消息传递-Java快速进阶教程
1. 概述
在本教程中,我们将探索使用 Spring AMQP 框架通过 AMQP 进行基于消息的通信。首先,我们将介绍消息传递的一些关键概念。然后,我们将继续一个实际示例。
2. 基于消息的通信
消息传递是一种在应用程序之间进行通信的技术。它依赖于异步消息传递,而不是基于同步请求响应的体系结构。消息的生产者和使用者通过称为消息代理的中间消息传递层分离。消息代理提供消息持久存储、消息过滤和消息转换等功能。
在用 Java 编写的应用程序之间进行消息传递的情况下,通常使用 JMS(Java 消息服务)API。对于不同供应商和平台之间的互操作性,我们将无法使用 JMS 客户端和代理。这就是AMQP派上用场的地方。
3. AMQP – 高级消息队列协议
AMQP 是用于异步消息通信的开放标准线路规范。它提供了应如何构造消息的说明。
3.1. Amqp 与 JMS 有何不同
由于 AMQP 是与平台无关的二进制协议标准,因此库可以用不同的编程语言编写,并在不同的环境中运行。
没有基于供应商的协议锁定,就像从一个 JMS 代理迁移到另一个 JMS 代理时的情况一样。有关更多详细信息,请参阅JMS 与AMQP 和了解 AMQP。一些广泛使用的AMQP代理是RabbitMQ,OpenAMQ和StormMQ。
3.2. AMQP 实体
简而言之,AMQP 由交换、队列和绑定组成:
- 交换机就像邮局或邮箱,客户端向AMQP交换机发布消息。有四种内置交换类型
- 直接交换 – 通过匹配完整的路由密钥将消息路由到队列
- 扇出交换 – 将消息路由到绑定到它的所有队列
- 主题交换 – 通过将路由密钥与模式匹配,将消息路由到多个队列
- 标头交换 – 根据消息标头路由消息
- 队列使用路由密钥绑定到交换
- 消息使用路由密钥发送到交易所。然后,交换将消息的副本分发到队列
3.3. Spring AMQP
Spring AMQP包括两个模块:spring-amqp和spring-rabbit。这些模块共同提供了以下抽象:
- AMQP 实体 – 我们使用消息、队列、绑定和交换类创建实体
- 连接管理 – 我们使用CachingConnectionFactory 连接到我们的 RabbitMQ 代理
- 消息发布 – 我们使用RabbitTemplate发送消息
- 消息消耗 – 我们使用 a@RabbitListener从队列中读取消息
4. 设置RabbitMQ
我们需要一个可供我们连接的 RabbitMQ 代理。最简单的方法是使用 Docker 为我们获取并运行 RabbitMQ 镜像:
docker run -d -p 5672:5672 -p 15672:15672 --name my-rabbit rabbitmq:3-management
我们公开端口 5672,以便我们的应用程序可以连接到 RabbitMQ。
而且,我们公开端口 15672,以便我们可以通过管理 UI:http://localhost:15672或 HTTP API:http://localhost:15672/api/index.html 查看我们的 RabbitMQ 代理正在做什么。
5. 创建我们的Spring Amqp 应用程序
因此,现在让我们创建我们的应用程序,以使用 Spring AMQP 发送和接收简单的“你好,世界!”消息。
5.1. Maven 依赖
为了将spring-amqp和spring-rabbit模块添加到我们的项目中,我们将spring-boot-starter-amqp依赖项添加到我们的pom.xml:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
</dependencies>
我们可以在Maven Central找到最新版本。
5.2. 连接到Rabbitmq Broker
我们将使用 Spring Boot 的自动配置来创建我们的ConnectionFactory、RabbitTemplate 和 RabbitAdmin bean。因此,我们使用默认用户名和密码“guest”在端口 5672 上连接到我们的 RabbitMQ 代理。因此,我们只需使用以下方法注释我们的应用程序@SpringBootApplication:
@SpringBootApplication
public class HelloWorldMessageApp {
// ...
}
5.3. 创建我们的队列
为了创建队列,我们只需定义一个Queue类型的bean。RabbitAdmin会找到这个,并将其绑定到默认交换机,并使用路由键“myQueue”:
@Bean
public Queue myQueue() {
return new Queue("myQueue", false);
}
我们将队列设置为非持久队列,以便在 RabbitMQ 停止时将删除队列及其上的任何消息。但请注意,重新启动我们的应用程序不会影响队列。
5.4. 发送我们的消息
让我们使用RabbitTemplate发送我们的“Hello, world!”消息:
rabbitTemplate.convertAndSend("myQueue", "Hello, world!");
5.5. 使用我们的消息
我们将通过以下方式注释方法来实现消息使用者@RabbitListener:
@RabbitListener(queues = "myQueue")
public void listen(String in) {
System.out.println("Message read from myQueue : " + in);
}
6. 运行我们的应用程序
首先,我们启动 RabbitMQ 代理:
docker run -d -p 5672:5672 -p 15672:15672 --name my-rabbit rabbitmq:3-management
然后,我们通过运行HelloWorldMessage.java 来运行 spring 启动应用程序,执行main() 方法:
mvn spring-boot:run -Dstart-class=com.baeldung.springamqp.simple.HelloWorldMessageApp
当应用程序运行时,我们将看到:
- 应用程序向默认交换发送消息,并将“myQueue”作为路由密钥
- 然后,队列“myQueue”接收消息
- 最后,监听方法使用来自“myQueue”的消息并将其打印到控制台上
我们还可以使用 RabbitMQ 管理页面http://localhost:15672查看我们的消息是否已发送和使用。