微服务--SpringAMQP

news/2024/12/21 22:13:04/

AMQP:高级消息队列协议,是应用程序之间传递业务消息的开放标准,与语言和平台无关,更符合微服务架构中独立性的要求。

SpringAMQP:基于AMQP协议定义的一套API规范,提供了模板来发送和接收消息。它包含两部分:spring-amqp是基础抽象,spring-rabbit是底层的默认实现。SpringAMQP利用SpringBoot实现了自动装配,使用非常方便。

SpringAMQP是Spring框架对AMQP(高级消息队列协议)的支持,它提供了一种简单而强大的方式与消息代理(如RabbitMQ)进行交互。SpringAMQP包含了发送和接收消息的模板化抽象层,以及基于消息驱动的POJO(Plain Old Java Object)的消息监听支持,极大地方便了RabbitMQ等消息代理在Spring应用中的集成和使用。

核心概念

  • ConnectionFactory:用于创建与消息代理之间的连接。
  • AmqpTemplate:用于发送和接收消息的主要接口,Spring Boot中通常使用RabbitTemplate作为其实现。
  • MessageConverter:用于在消息和对象之间进行转换的接口,Spring AMQP提供了多种消息转换器以方便消息的处理。
  • @RabbitListener:用于标注消息监听器方法的注解,指定该方法用于监听特定队列的消息。
  • @RabbitHandler:用于标注具体处理消息的方法的注解,常与@RabbitListener结合使用。

主要功能和特性

  1. 自动声明队列、交换机及其绑定关系:SpringAMQP可以自动根据配置声明队列、交换机和它们之间的绑定关系,减少了手动配置的繁琐。

  2. 基于注解的监听器模式:通过@RabbitListener注解,可以方便地定义消息监听器,实现异步接收消息。

  3. 封装了RabbitTemplate工具:RabbitTemplate提供了发送消息的简便方法,如convertAndSend,可以轻松地发送消息到指定的队列或交换机。

使用场景

SpringAMQP在微服务架构中常用于以下场景:

  1. 异步通信微服务间通过消息队列进行异步通信,解耦服务间的直接调用,提高系统的可扩展性和稳定性。

  2. 负载均衡:当消息处理比较耗时或处理速度不一致时,可以通过多个消费者共同处理消息,实现负载均衡。

  3. 消息广播:利用RabbitMQ的交换机特性,可以实现消息的广播,即将消息发送给多个队列。

使用步骤

  1. 引入依赖:在父工程或微服务项目中引入SpringAMQP的starter依赖。

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency>
  • 配置RabbitMQ:在application.ymlapplication.properties文件中配置RabbitMQ的地址、端口、用户名、密码和虚拟主机等信息。

# application.properties 示例  
spring.rabbitmq.host=localhost  
spring.rabbitmq.port=5672  
spring.rabbitmq.username=guest  
spring.rabbitmq.password=guest
  • 定义队列 :在Spring AMQP中,你可以通过配置类或使用注解来定义队列。但在这个基础示例中,我们假设RabbitMQ管理界面或默认配置已经创建了队列。不过,为了完整性,这里展示如何通过配置类定义队列(虽然在这个简单示例中可能不是必需的)
import org.springframework.amqp.core.Queue;  
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  @Configuration  
public class RabbitMQConfig {  @Bean  public Queue myQueue() {  return new Queue("myQueue", true); // 队列名称,是否持久化  }  
}
  • 发送消息:在发送者服务中,通过注入的RabbitTemplate对象,调用convertAndSend等方法发送消息。

  • 接收消息:在接收者服务中,定义消息监听器,使用@RabbitListener注解标注方法,用于接收消息。

示例

发送消息

@Autowired 
private RabbitTemplate rabbitTemplate; public void sendMessage(String queueName, String message) { rabbitTemplate.convertAndSend(queueName, message); 
}

接收消息

@Component 
public class MessageListener { @RabbitListener(queues = "simple.queue") 
public void receiveMessage(String message) { System.out.println("Received message: " + message); } 
}

SpringAMQP是一个功能强大的消息中间件集成框架,能够简化消息队列的开发和使用。通过引入依赖、配置RabbitMQ、发送和接收消息等步骤,可以轻松实现基于消息的应用程序开发。

Spring AMQP发布订阅者模式

Spring AMQP发布订阅者模式是一种消息传递模式,它允许生产者(发布者)将消息发送到交换机,交换机再将消息路由到一个或多个队列中,由消费者(订阅者)从队列中接收并处理这些消息。这种模式实现了生产者与消费者之间的解耦,提高了系统的可扩展性和灵活性。以下是Spring AMQP发布订阅者模式的详细解析:

  • 发布者(Publisher):发送消息的应用程序或组件。
  • 订阅者(Subscriber):接收并处理消息的应用程序或组件。
  • 交换机(Exchange):接收生产者发送的消息,并根据路由规则将消息分发到一个或多个队列中。
  • 队列(Queue):存储消息的容器,消费者从队列中取出消息进行处理。

交换机类型

在Spring AMQP中,发布订阅者模式通常与以下类型的交换机一起使用:

  1. Fanout交换机:将接收到的所有消息广播到所有与之绑定的队列中,忽略路由键。这种类型适用于需要将消息发送给所有订阅者的场景。
  2. Direct交换机:通过路由键精确匹配消息的路由。如果消息的路由键与队列绑定的路由键完全一致,则消息会被投递到该队列。这种类型适用于需要将消息发送给特定订阅者的场景。
  3. Topic交换机:根据路由键的模式进行匹配,类似于正则表达式。如果队列绑定的路由键模式与消息的路由键匹配,则消息会被投递到该队列。这种类型适用于需要根据消息的不同类型或属性将消息发送给不同订阅者的场景。

实现步骤

  1. 配置交换机和队列:在Spring Boot项目中,可以通过配置类(使用@Configuration注解)来声明交换机和队列,并通过@Bean注解将它们注册为Spring容器中的Bean。
  2. 绑定交换机和队列:使用BindingBuilder类将队列与交换机进行绑定,并指定路由键(对于Direct和Topic交换机)。
  3. 发送消息:在生产者中,使用RabbitTemplateconvertAndSend方法将消息发送到指定的交换机和路由键。
  4. 接收消息:在消费者中,使用@RabbitListener注解来监听队列中的消息,并编写相应的方法来处理接收到的消息。

注意事项

  • 消息确认:为了确保消息的可靠传递,可以启用消息确认机制。这样,当消费者成功处理消息后,会向RabbitMQ发送确认信号,RabbitMQ才会将消息从队列中删除。
  • 持久化:为了确保在RabbitMQ服务器重启后消息不会丢失,可以将交换机、队列和消息都设置为持久化。
  • 错误处理:在消费者中,应该添加适当的错误处理逻辑,以便在消息处理失败时能够进行重试或记录错误日志。

实际案例

案例背景

假设我们有一个电商平台,其中包含了订单系统、库存系统和支付系统。当订单系统生成一个新订单时,需要通知库存系统减少相应商品的库存,并通知支付系统处理支付。这里,我们可以使用RabbitMQ作为消息中间件,通过Spring AMQP来发送和接收消息。

案例实现

1. 环境准备

  • 安装RabbitMQ服务器,并启动服务。
  • 在Spring Boot项目中引入Spring AMQP的依赖。

2. 配置RabbitMQ

在Spring Boot的application.ymlapplication.properties文件中配置RabbitMQ的连接信息,包括主机名、端口、虚拟主机、用户名和密码等。

spring:  rabbitmq:  host: localhost  port: 5672  username: guest  password: guest  virtual-host: /

3. 定义消息模型

在这个案例中,我们可以定义一个简单的消息模型,包含订单ID和商品ID等信息。为了简化,这里只使用字符串作为消息体。

4. 生产者实现

在订单系统中,当新订单生成时,使用RabbitTemplate发送消息到RabbitMQ的交换机。

@Autowired  
private RabbitTemplate rabbitTemplate;  public void sendOrderCreatedMessage(String orderId, String productId) {  String message = "Order created: " + orderId + ", Product: " + productId;  String exchangeName = "order.exchange";  String routingKey = "order.created";  rabbitTemplate.convertAndSend(exchangeName, routingKey, message);  
}

5. 消费者实现

在库存系统和支付系统中,分别编写消息监听器来接收订单创建的消息,并处理相应的业务逻辑。

库存系统消费者

@Component  
public class InventoryConsumer {  @RabbitListener(queues = "inventory.queue")  public void handleOrderCreated(String message) {  // 解析消息,获取订单ID和商品ID  // 调用库存减少的API或方法  System.out.println("Inventory system received: " + message);  // 模拟库存减少操作  System.out.println("Inventory updated for the order.");  }  
}

注意:这里假设库存系统的队列inventory.queue已经通过某种方式(如配置类)绑定到了order.exchange交换机,并且路由键为order.created

支付系统消费者(类似实现,不再赘述)。

6. 交换机和队列的配置

在Spring Boot项目中,可以通过配置类来声明交换机、队列和绑定关系。但在这个案例中,为了简化,我们假设这些配置已经在RabbitMQ的管理界面中手动完成,或者通过其他方式(如Docker Compose文件、Kubernetes配置等)在部署时自动完成。


http://www.ppmy.cn/news/1533816.html

相关文章

Linux防火墙配置绿色端口,解决无法访问java服务的问题

配置防火墙&#xff0c;添加或删除端口&#xff0c;需要有root权限。 防火墙常用命令如下&#xff1a; 1.查看防火墙状态&#xff1a; systemctl status firewalldactive(running)&#xff1a;开启状态&#xff0c;正在运行中 inactive(dead)&#xff1a;关闭状态&#xff0…

期权卖方如何选择铁矿石行权价?期权策略盈亏分析计算方式详解

截止9月30日收盘&#xff0c;铁矿石2411合约收盘价825元/吨。日线级别处于上涨趋势中 假设以825元为最新价&#xff0c;假设后市铁矿石期货价格会下跌&#xff0c;期权卖方应该如何选择行权&#xff1f; 卖出行权价800的看涨期权&#xff0c;期权报价37.9&#xff0c;一手权利…

XML与JSON的用法与区别

XML和JSON各有优劣&#xff0c;选择哪种数据格式取决于具体的应用场景和需求。对于需要严格数据约束和结构化数据的场景&#xff0c;XML可能是更好的选择&#xff1b;而对于追求简洁、高效和灵活性的场景&#xff0c;JSON则更具优势。在实际开发中&#xff0c;根据项目的具体要…

Unity实战案例全解析:RTS游戏的框选和阵型功能(5)阵型功能 优化

前篇&#xff1a;Unity实战案例全解析&#xff1a;RTS游戏的框选和阵型功能&#xff08;4&#xff09;阵型功能-CSDN博客 本案例来源于unity唐老狮&#xff0c;有兴趣的小伙伴可以去泰克在线观看该课程 我只是对重要功能进行分析和做出笔记分享&#xff0c;并未无师自通&#x…

当MySQL中无法使用with关键词时该怎么办?

当MySQL中无法使用with关键词时该怎么办&#xff1f; withc1 as (SELECT count(*) FROM database.table1),c2 as (SELECT count(*) FROM database.table2),c3 as (SELECT count(*) FROM database.table3),c4 as (SELECT count(*) FROM database.table4),c5 as (SELECT count(*…

适用于 Windows 10 的最佳 PDF 编辑器列表,可帮助更改 PDF 文件。

PDF 是一种流行的、多功能且安全的文件格式&#xff0c;用于在线共享文档。但是&#xff0c;如果没有合适的应用程序&#xff0c;查看和编辑 PDF 文件可能会变得复杂。 幸运的是&#xff0c;有很多 PDF 编辑器可以帮助您更正重要文档上的错误、填写表格、为合同添加签名、更改…

Pikachu-xss防范措施 - href输出 js输出

总体原则&#xff1a; 输入做过滤&#xff0c;输出做转义 过滤&#xff1a;根据业务需要进行过滤&#xff0c;如&#xff1a;输入点要求输入手机号&#xff0c;则只允许输入手机号格式的数字&#xff1b; 转义&#xff1a;所有输出到前端的数据&#xff0c;都根据输出点进行转…

先进制造aps专题二十六 基于强化学习的人工智能ai生产排程aps模型简介

基于强化学习的人工智能ai生产排程模型简介 人工智能ai能不能做生产排程&#xff1f; 答案是肯定的。 ai的算法分两类&#xff0c;一类是学习&#xff0c;一类是搜索。 而生产排程问题&#xff0c;它是一个搜索问题&#xff0c;本质上&#xff0c;它和下围棋是一样的 我们…