rabbitMQ的学习
什么是MQ?
MQ(message queue),从字面意思上看,本质是个队列,FIFO 先入先出,只不过队列中存放的内容是message 而已,还是一种跨进程的通信机制,用于上下游传递消息。在互联网架构中,MQ 是一种非常常见的上下游“逻辑解耦+物理解耦”的消息通信服务。使用了 MQ 之后,消息发送上游只需要依赖 MQ,不用依赖其他服务。
为什么要使用MQ?
1.流量消峰
举个例子,如果订单系统最多能处理一万次订单,这个处理能力应付正常时段的下单时绰绰有余,正
常时段我们下单一秒后就能返回结果。但是在高峰期,如果有两万次下单操作系统是处理不了的,只能限制订单超过一万后不允许用户下单。使用消息队列做缓冲,我们可以取消这个限制,把一秒内下的订单分散成一段时间来处理,这时有些用户可能在下单十几秒后才能收到下单成功的操作,但是比不能下单的体验要好。
2.应用解耦
以电商应用为例,应用中有订单系统、库存系统、物流系统、支付系统。用户创建订单后,如果耦合
调用库存系统、物流系统、支付系统,任何一个子系统出了故障,都会造成下单操作异常。当转变成基于消息队列的方式后,系统间调用的问题会减少很多,比如物流系统因为发生故障,需要几分钟来修复。在这几分钟的时间里,物流系统要处理的内存被缓存在消息队列中,用户的下单操作可以正常完成。当物流系统恢复后,继续处理订单信息即可,中单用户感受不到物流系统的故障,提升系统的可用性。
3.异步处理
有些服务间调用是异步的,例如 A 调用 B,B 需要花费很长时间执行,但是 A 需要知道 B 什么时候可
以执行完,以前一般有两种方式,A 过一段时间去调用 B 的查询 api 查询。或者 A 提供一个 callback api,B 执行完之后调用 api 通知 A 服务。这两种方式都不是很优雅,使用消息总线,可以很方便解决这个问题,A 调用 B 服务后,只需要监听 B 处理完成的消息,当 B 处理完成后,会发送一条消息给 MQ,MQ 会将此消息转发给 A 服务。这样 A 服务既不用循环调用 B 的查询 api,也不用提供 callback api。同样 B 服务也不用做这些操作。A 服务还能及时的得到异步处理成功的消息。
1.RabbitMQ概述:
1:rabbitMQ概念:
RabbitMQ 是一个消息中间件:它接受并转发消息。你可以把它当做一个快递站点,当你要发送一个包裹时,你把你的包裹放到快递站,快递员最终会把你的快递送到收件人那里,按照这种逻辑 RabbitMQ 是一个快递站,一个快递员帮你传递快件。RabbitMQ 与快递站的主要区别在于,它不处理快件而是接收,存储和转发消息数据。
2. 基本概念
- 生产者(Producer)
生产者是指向消息队列发送消息的应用程序或组件。生产者负责创建消息并将其发送到消息队列中,消息可以包含任何类型的信息,如任务、事件、通知等。生产者通常不关心消息被哪些消费者接收和处理,它只负责将消息发送到消息队列中。
- 消费者(Consumer)
消费者是从消息队列中接收消息并进行处理的应用程序或组件。消费者订阅一个或多个队列,从队列中获取消息并对其进行处理。消费者可以根据特定的业务逻辑来处理消息,比如执行任务、更新数据、发送通知等。消费者的存在使得消息的处理变得异步化,提高了系统的可伸缩性和灵活性。
- 消息队列(Message Queue)
消息队列是用于存储消息的缓冲区,它允许生产者将消息发送到队列中,然后消费者可以从队列中获取消息并进行处理。消息队列起到了解耦的作用,使得生产者和消费者之间不需要直接通信,从而降低了系统组件之间的耦合度。
- 交换机(Exchange)
交换机负责接收生产者发送的消息,并根据特定的路由规则将消息发送到一个或多个队列中。交换机的作用类似于邮局的分拣中心,根据邮件的地址将邮件分发到不同的邮箱中。RabbitMQ 提供了不同类型的交换机,比如直连交换机(Direct Exchange)、主题交换机(Topic Exchange)、扇出交换机(Fanout Exchange)等,每种类型的交换机都有不同的消息路由规则。
- 绑定(Binding)
绑定定义了交换机如何将消息路由到特定的队列中。生产者通过将消息发送到交换机,并通过绑定规则指定消息的路由键(Routing Key),交换机根据路由规则将消息发送到一个或多个队列中。绑定将交换机和队列连接起来,并定义了消息的路由规则,是消息路由的关键配置之一。
2. RabbitMQ 的核心概念
- 队列(Queue):消息的存储位置,在消费者之间传递消息。
- 交换机(Exchange):接收消息,并根据路由规则将消息转发到一个或多个队列。
- 绑定(Binding):连接交换机和队列,定义了消息的路由规则。
3. RabbitMQ 的工作流程
- 生产者将消息发送到交换机。
- 交换机根据路由规则将消息发送到一个或多个队列。
- 消费者从队列中获取消息并处理。
4. RabbitMQ 的优点
- 可靠性:保证消息传递的可靠性和一致性。
- 灵活性:支持多种消息传递模式,如点对点、发布/订阅等。
- 可扩展性:可以通过集群方式实现可扩展性。
- 解耦:降低系统组件之间的耦合度。
- 消息确认:支持消息的确认机制,确保消息被正确处理。
5. RabbitMQ 的应用场景
- 异步通信:在分布式系统中进行异步通信。
- 任务队列:实现任务的异步处理。
- 日志处理:收集和处理大量日志数据。
- 事件驱动:基于事件的系统架构。
- 实时数据处理:处理实时的大数据流。
总的来说,RabbitMQ 是一个功能强大且灵活的消息代理软件,通过其丰富的特性和机制,可以帮助开发人员构建可靠、可扩展的分布式系统,实现消息传递、异步通信等功能。
2.RabbitMQ模式:
1. 点对点模式(Point-to-Point)
- 特点:在点对点模式下,一个消息只能被一个消费者接收和处理,确保消息只被处理一次。
- 工作原理:生产者将消息发送到队列中,只有一个消费者可以从队列中获取消息进行处理。
- 适用场景:适用于需要确保每条消息只被一个消费者处理的情况,如任务分发、工作队列等。
2. 发布/订阅模式(Publish/Subscribe)
- 特点:在发布/订阅模式下,一个消息可以被多个消费者同时接收和处理,实现消息的广播传递。
- 工作原理:生产者将消息发送到交换机,交换机将消息广播到绑定的多个队列,每个队列对应一个消费者。
- 适用场景:适用于需要将消息广播给多个消费者的情况,如通知、日志订阅等。
3. 主题模式(Topic)
- 特点:主题模式是一种灵活的消息路由方案,允许生产者根据主题进行消息的精确匹配和发送。
- 工作原理:生产者将消息发送到主题交换机,并指定一个主题(Topic)作为消息的路由键,交换机根据主题将消息发送到匹配主题的队列中。
- 适用场景:适用于需要根据消息内容进行灵活路由和过滤的情况,如新闻订阅、事件处理等。
4. 扇出模式(Fanout)
- 特点:扇出模式是一种消息广播方案,交换机将接收到的消息广播到所有绑定的队列中。
- 工作原理:生产者将消息发送到扇出交换机,交换机将消息广播到所有与之绑定的队列中,每个消费者都会接收到相同的消息副本。
- 适用场景:适用于需要将消息广播给所有消费者的情况,如实时数据推送、广播通知等。
3.rabbitMQ的应用
-
导入依赖
<!--rabbitmq 依赖客户端--> <dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-client</artifactId> <version>5.8.0</version> </dependency>
-
应用场景
-
发布/订阅模式:文章来源:https://www.toymoban.com/news/detail-837133.html
- 场景描述:一个生产者发送消息到交换机(exchange),多个消费者通过绑定不同的队列(queue)来接收消息,实现一对多的消息发布和订阅机制。
- Java 代码示例:
// 生产者发送消息 ConnectionFactory factory = new ConnectionFactory(); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); channel.exchangeDeclare("myExchange", "fanout"); channel.basicPublish("myExchange", "", null, "Hello, world!".getBytes()); // 消费者接收消息 ConnectionFactory factory = new ConnectionFactory(); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); channel.exchangeDeclare("myExchange", "fanout"); String queueName = channel.queueDeclare().getQueue(); channel.queueBind(queueName, "myExchange", ""); Consumer consumer = new DefaultConsumer(channel) { public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String message = new String(body, "UTF-8"); System.out.println("Received: " + message); } }; channel.basicConsume(queueName, true, consumer);
-
工作队列模式:文章来源地址https://www.toymoban.com/news/detail-837133.html
- 场景描述:多个消费者共享同一个队列,消息会被平均分配给各个消费者,实现任务的并行处理。
- Java 代码示例:
// 生产者发送消息 ConnectionFactory factory = new ConnectionFactory(); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); channel.queueDeclare("myQueue", false, false, false, null); channel.basicPublish("", "myQueue", null, "Hello, world!".getBytes()); // 消费者接收消息 ConnectionFactory factory = new ConnectionFactory(); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); channel.queueDeclare("myQueue", false, false, false, null); Consumer consumer = new DefaultConsumer(channel) { public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String message = new String(body, "UTF-8"); System.out.println("Received: " + message); } }; channel.basicConsume("myQueue", true, consumer);
-
3.RabbitMQ高级特性:
-
可靠性:
- 持久化消息:RabbitMQ 支持将消息持久化到磁盘,即使在服务器重启后也能保证消息不丢失。
- 消息确认机制:生产者可以通过消息确认机制确保消息被正确发送到队列,消费者可以通过手动确认消息来保证消息不会丢失。
-
灵活的消息路由:
- Exchange 类型:RabbitMQ 支持多种 Exchange 类型,如 direct、fanout、topic 和 headers,可以根据不同的路由规则将消息发送到指定的队列。
-
消息确认和补偿:
- 事务支持:RabbitMQ 支持事务,生产者可以通过事务来确保消息的原子性,要么全部发送成功,要么全部失败。
- 发布确认模式:生产者可以通过发布确认模式(Publisher Confirms)来确保消息被正确发送到 RabbitMQ 服务器。
-
消息优先级:
- 消息优先级队列:RabbitMQ 支持设置消息的优先级,高优先级的消息将会被优先处理。
-
延迟队列:
- 延迟消息插件:通过 RabbitMQ 插件或者第三方插件实现延迟队列,可以实现消息在特定时间后才被消费。
-
死信队列:
- 死信交换机:RabbitMQ 支持配置死信交换机和死信队列,用于处理无法被消费的消息,例如超时消息或者消费者拒绝消息。
-
集群和高可用性:
- 集群部署:RabbitMQ 支持集群部署,多个节点之间可以进行数据复制和负载均衡。
- 镜像队列:通过镜像队列可以将队列的数据复制到多个节点,提高消息的可靠性和可用性。
-
插件系统:
- 插件支持:RabbitMQ 提供了丰富的插件系统,可以通过插件扩展 RabbitMQ 的功能,如管理插件、监控插件等。
4.RabbitMQ与Spring整合:
-
使用 Spring Boot 集成 RabbitMQ:
- 在 Spring Boot 项目中,可以通过简单地添加相应的依赖来集成 RabbitMQ。Spring Boot 提供了
spring-boot-starter-amqp
starter 来简化 RabbitMQ 的集成和配置。 - 在
application.properties
或application.yml
文件中配置 RabbitMQ 的连接信息、交换机、队列等信息。
- 在 Spring Boot 项目中,可以通过简单地添加相应的依赖来集成 RabbitMQ。Spring Boot 提供了
-
使用 Spring AMQP:
- Spring AMQP 是 Spring 对 AMQP(包括 RabbitMQ)的支持库,提供了一组模板和工具类来方便地使用 RabbitMQ。
- 可以在 Spring 配置文件中配置
RabbitTemplate
、SimpleMessageListenerContainer
等 Bean 来发送和接收消息。
-
使用 @RabbitListener 注解:
- Spring 提供了
@RabbitListener
注解,可以用于标记消息监听方法,使得方法能够接收指定队列中的消息。 - 通过在方法上使用
@RabbitListener
注解,可以方便地实现消息的消费。
- Spring 提供了
-
使用消息转换器:
- Spring 提供了消息转换器(Message Converter)来简化消息的序列化和反序列化过程。可以通过配置
MessageConverter
来自定义消息的转换方式。
- Spring 提供了消息转换器(Message Converter)来简化消息的序列化和反序列化过程。可以通过配置
-
使用 RabbitAdmin 自动声明队列和交换机:
- 可以通过配置
RabbitAdmin
Bean 来在启动时自动声明队列和交换机,避免手动创建和维护队列和交换机的繁琐工作。
- 可以通过配置
5.RabbitMQ性能调优:
-
调整内存限制:
- 在 RabbitMQ 的配置文件中(通常是
rabbitmq.config
或rabbitmq.conf
),可以设置内存限制参数,如vm_memory_high_watermark
,vm_memory_high_watermark_paging_ratio
等,来控制 RabbitMQ 使用的内存上限。
- 在 RabbitMQ 的配置文件中(通常是
-
优化磁盘使用:
- 配置队列、交换机等对象的持久化方式,可以选择将消息存储到磁盘以确保消息持久性。可以通过配置
queue_mode
、queue_type
等参数进行调整。
- 配置队列、交换机等对象的持久化方式,可以选择将消息存储到磁盘以确保消息持久性。可以通过配置
-
连接和通道管理:
- 控制并发连接数和通道数,避免过多的连接和通道导致资源竞争和性能下降。可以通过配置
max_connections
、max_channels_per_connection
等参数限制连接和通道数量。
- 控制并发连接数和通道数,避免过多的连接和通道导致资源竞争和性能下降。可以通过配置
-
消费者端调优:
- 在消费者端设置合适的预取值(prefetch count),可以控制一次从 RabbitMQ 服务器获取的消息数量,避免一次性获取过多消息导致性能问题。
- 使用手动消息确认模式,确保消息被正确处理后再进行确认,避免消息丢失或重复消费。
-
生产者端调优:
- 批量发送消息可以提高消息发送的效率。可以考虑批量发送消息而不是逐条发送消息。
- 对于需要发送大量消息的场景,可以考虑使用发布确认模式(Publisher Confirms)来确保消息被正确发送到 RabbitMQ 服务器。
-
集群和高可用性:
- 配置 RabbitMQ 集群可以提高系统的可靠性和可用性。通过在多个节点之间进行数据复制和负载均衡来实现高可用性。
- 配置镜像队列可以将队列的数据复制到多个节点,提高消息的可靠性和可用性。
-
监控和调试:
- 使用 RabbitMQ 提供的管理插件来监控 RabbitMQ 的运行状态,及时发现和解决问题。
- 使用日志系统记录 RabbitMQ 的运行日志,便于排查和分析问题。
6.RabbitMQ集群高可用性:
-
多节点集群:
- RabbitMQ 高可用性的基础是构建一个由多个节点组成的集群。每个节点都具有相同的数据副本,并能够接收和处理客户端的请求。
-
数据复制:
- 在 RabbitMQ 集群中,队列、交换机和绑定等元数据以及消息数据都可以进行数据复制。当一个节点上的数据发生变化时,这些变化会被复制到集群中的其他节点上。
-
镜像队列:
- RabbitMQ 提供了镜像队列(Mirrored Queue)的功能,可以将队列的数据复制到多个节点上,确保即使某个节点发生故障,队列中的消息数据仍然可用。
-
自动化故障切换:
- 当集群中的某个节点发生故障时,RabbitMQ 集群可以自动将受影响的队列和交换机从故障节点迁移到其他正常节点上,实现故障切换并确保系统的连续性。
-
负载均衡:
- RabbitMQ 集群会自动对客户端的连接请求进行负载均衡,将请求分发到集群中的各个节点上,避免单个节点过载或性能瓶颈。
-
集群监控和管理:
- RabbitMQ 集群提供了管理插件,可以通过 Web 界面或 API 来监控集群的运行状态,查看节点的健康状况和负载情况,进行故障诊断和管理操作。
-
节点互联:
- 集群中的各个节点之间需要建立互联,确保节点之间可以进行数据同步、故障切换和通信。
7.RabbitMQ安全性:
-
身份认证:
- RabbitMQ 支持多种身份认证方式,如用户名和密码、LDAP 认证、OAuth2 认证等。通过设置合适的认证方式和权限控制,可以防止未经授权的用户访问 RabbitMQ。
-
访问控制:
- RabbitMQ 支持基于虚拟主机(vhost)、队列和交换机等级别的访问控制。可以通过设置权限策略、用户角色等方式来限制用户的访问范围和操作权限,保护 RabbitMQ 中存储的数据和资源。
-
加密传输:
- RabbitMQ 支持 SSL/TLS 加密通信,可以确保所有数据在传输过程中都是加密的。通过配置 RabbitMQ 和客户端之间的 SSL/TLS 连接,可以有效地防止网络窃听和数据篡改等风险。
-
安全插件:
- RabbitMQ 提供了一些安全插件,如 rabbitmq-auth-backend-ldap、rabbitmq-auth-backend-oauth2 等,可以增强 RabbitMQ 的身份认证和访问控制功能。
-
日志审计:
- RabbitMQ 可以记录所有的管理操作、消息发送和接收等事件,并将这些事件记录到日志文件中。通过对日志文件进行分析和监控,可以及时发现和处理安全漏洞和异常情况。
-
系统更新和维护:
和客户端之间的 SSL/TLS 连接,可以有效地防止网络窃听和数据篡改等风险。 -
安全插件:
- RabbitMQ 提供了一些安全插件,如 rabbitmq-auth-backend-ldap、rabbitmq-auth-backend-oauth2 等,可以增强 RabbitMQ 的身份认证和访问控制功能。
-
日志审计:
- RabbitMQ 可以记录所有的管理操作、消息发送和接收等事件,并将这些事件记录到日志文件中。通过对日志文件进行分析和监控,可以及时发现和处理安全漏洞和异常情况。
-
系统更新和维护:
- 对于 RabbitMQ 的安全性而言,定期进行系统更新和维护是非常重要的。及时更新 RabbitMQ 的版本、插件和操作系统等组件,修补已知的安全漏洞和缺陷,可以有效地提高系统的稳定性和安全性。
到了这里,关于rabbitMQ的学习的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!