RPC
RPC(远程过程调用),简单来说,就是一个进程A向另外一个进程B请求服务。进程A调用进程B的服务,就好像在调用自己进程的服务方法一样,无需关心内部的实现细节。
传统的进程之间通信,是由服务端监听在某个端口,客户端进程通过远程过程调用(RPC)方式和服务端进程进行通信,这种通信方式,当消息过多时候,远程过程调用容易造成消息阻塞。转为不可中断睡眠状态的进程。为了解决此问题,消息中间件应用而生。
队列(MQ)概念
MQ全称为MessageQueue,消息队列(MQ)是一种应用程序对应用程序的通信方法。
应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们。
消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术。
排队指的是应用程序通过队列来通信。队列的使用除去了接收和发送应用程序同时执行的要求。
RabbitMQ支持多种工作模式
- 简单模式(Simple Mode): 在简单模式下,一个生产者向一个队列发送消息,然后一个消费者从该队列中接收和处理消息。这是最基本的工作模式,适用于简单的应用场景。
- 工作队列模式(Work Queue Mode): 工作队列模式也被称为任务分发模式。在这种模式下,一个生产者向一个队列发送消息,多个消费者并行地接收和处理消息。每个消息只能被一个消费者处理,通过竞争的方式实现负载分担。
- 发布/订阅模式(Publish/Subscribe Mode): 在发布/订阅模式下,一个生产者将消息发送到交换机(Exchange),而不是直接发送到队列。交换机将消息广播到绑定到它的所有队列,每个队列都可以有一个或多个消费者进行订阅并接收消息。这种模式实现了一对多的消息传递。
- 路由模式(Routing Mode): 路由模式也称为直连模式。在这种模式下,生产者将消息发送到交换机,并指定一个路由键(Routing Key)。交换机根据路由键将消息路由到特定的队列,消费者只从绑定了特定路由键的队列中接收消息。
- 主题模式(Topic Mode): 主题模式是一种灵活的工作模式,它结合了直连模式和通配符模式。在主题模式下,生产者将消息发送到交换机,并指定一个主题(Topic)。交换机根据主题和通配符匹配规则将消息路由到匹配的队列,消费者可以使用通配符来订阅特定的消息主题。
名词
- 消息代理中间件:RabbitMQ充当了消息的中间媒介,使得不同应用程序或服务之间能够进行异步通信。它接收来自发送者(生产者)的消息,并将其路由到接收者(消费者)。
- Publisher-Subscriber模型:在RabbitMQ中,消息的发送者称为发布者(Publisher),消息的接收者称为订阅者(Subscriber)。发布者发布消息到交换机,而订阅者从队列中获取并处理这些消息。
- Exchange(交换机):交换机接收来自发布者的消息,并根据预设的路由规则将消息路由到一个或多个队列。它可以根据消息的路由键(routing key)进行匹配,采用不同的路由方式,如直连、主题、头部和扇型。
- Queue(队列):队列用于存储消息,采用先进先出(FIFO)的方式进行消息的存储和处理。订阅者可以绑定到特定的队列上,并从队列中取出消息进行处理。
- Message(消息):消息是RabbitMQ中的基本单位,它由发布者发布,并由交换机路由到队列。消息可以包含任意类型的数据,如文本、JSON、二进制等。
- Connection(连接):连接是指发布者或订阅者与RabbitMQ之间建立的网络连接。通过连接,可以发送和接收消息。
- Channel(通道):通道是建立在连接之上的信道,用于发送和接收消息。在RabbitMQ中,大部分的操作都是在通道的上下文中进行的,通过多个通道可以并行地进行消息的发送和接收。
- Consumer(消费者):消费者是接收和处理消息的应用程序或服务。它连接到特定的队列,并从队列中获取消息进行处理。
- Acknowledgement(消息确认):消费者在成功处理一条消息后,向RabbitMQ发送确认消息,告知RabbitMQ该消息已被成功处理。消息确认保证了消息的可靠性传递,避免消息的丢失。
- Dead-Letter Queue(死信队列):当消息无法被消费者处理或达到了一定的超时时间,RabbitMQ会将这些消息发送到死信队列。死信队列可以用于后续的错误处理或日志记录。
- 可靠性和持久化:RabbitMQ支持消息的持久化,确保即使在发生故障或重启后,消息也不会丢失。可以通过将交换机和队列设置为持久化,以及将消息设置为持久化来实现可靠性。
- 高可用性和集群:RabbitMQ支持搭建高可用性的集群,通过在多台服务器上运行多个节点来实现水平扩展和容错性。
- RabbitMQ是被广泛应用于各种场景中的消息代理中间件,它可以用于解耦系统、实现负载均衡、处理大规模并发等。通过合理地设计和使用RabbitMQ,可以构建出稳健、可靠的分布式应用系统。
工作流程
生产者发送消息的流程
- 生产者连接RabbitMQ,建立TCP连接( Connection),开启信道(Channel)
- 生产者声明一个Exchange(交换器),并设置相关属性,比如交换器类型、是否持久化等
- 生产者声明一个队列井设置相关属性,比如是否排他、是否持久化、是否自动删除等
- 生产者通过bindingKey (绑定Key)将交换器和队列绑定( binding )起来
- 生产者发送消息至RabbitMQ Broker,其中包含routingKey (路由键)、交换器等信息
- 相应的交换器根据接收到的routingKey 查找相匹配的队列。
- 如果找到,则将从生产者发送过来的消息存入相应的队列中。
- 如果没有找到,则根据生产者配置的属性选择丢弃还是回退给生产者
- 关闭信道。
- 关闭连接。
消费者接收消息的过程
- 消费者连接到RabbitMQ Broker ,建立一个连接(Connection ) ,开启一个信道(Channel) 。
- 消费者向RabbitMQ Broker 请求消费相应队列中的消息,可能会设置相应的回调函数, 以及做一些准备工作
- 等待RabbitMQ Broker 回应并投递相应队列中的消息, 消费者接收消息。
- 消费者确认( ack) 接收到的消息。
- RabbitMQ 从队列中删除相应己经被确认的消息。
- 关闭信道。
- 关闭连接。
- 生产者创建并发送消息,发布到交换机。
- 交换机根据路由规则将消息路由到一个或多个队列。
- 消费者从队列中获取消息进行处理。
- 消费者完成处理后发送确认消息给RabbitMQ。
- RabbitMQ收到确认消息后,将消息标记为已传递并从队列中删除。
- 如果消息无法被消费者处理或达到超时时间,可能会进入死信队列待后续处理。
理解
1、交换机和队列关系
- 消息发送给交换机,交换机路由给队列;
- 消费者向交换机发送消息,交换机需要绑定队列,否则消息会丢失,因为交换机不能存储消息,只能路由和转发消息;
- 当多个队列绑定同一个交换机,向交换机发送的消息,会被绑定交换机的所有队列收到消息;
2、虚拟主机
- 虚拟机共享一台服务器,实现不同虚拟机之间相互隔离。
- 交换机和队列都有自己所属的虚拟主机
- 每个虚拟机里边有一个或多个交换机,每个交换机关联一个或多个队列。
- 每个项目一个用户,每个用户可以创建自己的虚拟主机
客户端
rabbitmq支持各种语言的客户端,可以基于语言和rabbitmq进行交互。
- AMQP
Advanced Message Queuing Protocol,是用于在应用程序之间传递业务消息的开放标准。该协议与语言和平台无关,更符合微服务中独立性的要求。 - Spring AMQP
Spring AMQP是基于AMQP协议定义的一套API规范,提供了模板来发送和接收消息。包含两部分,其中spring-amqp是基础抽象,spring-rabbit是底层的默认实现。