RabbitMQ与AMQP模型概览
一、RabbitMQ简介
AMQP:是jms中的高级的协议。RabbitMQ是采用Erlang语言实现AMQP协议的消息中间件,AMQP全称是Advanced Message Queue Prorocolg,高级消息队列协议。它是应用层协议的一个开放标准,为面向消息的中间件设计,基于此协议的客户端与消息中间件可传递消息,并不受产品,开发语言等条件的限制。做秒杀的时候会经常用到这个消息中间,因为它是高并发的。
用消息中间件的好处:
1、可以解耦 2、异步处理。 3、异构处理(比如一款产品可以用很多种语言开发,比如用go语言和用java语言开发要实现通信,我们能够想到的就是消息中间件)。
二、消息模型
2.1、MQ消息模型
所有MQ(消息中间件)一般有两种传递模式:点对点模式和发布/订阅模式
A、点对对模式是基于队列的,消息生产者创建消息,然后发送 消息给队列,消费者订阅队列,并从队列中获取信息。模型如下图所示:
点对点模型的特点:
①、queue不能存储已经消费的消息,消费者不可能消费到已经被消费的消息。
②、每个消息只有一个消费者和一个生产者
③、生产者发送消息和消费者消费消息是异步解耦的(不同的时候会触发的,也有可能是不同语言编写的)
④、消费者接收到消息后,需要发送ACK确认。
B、发布订阅模式定义了如何向一个内容节点发送和订阅消息,消息发送者将消息发送到某一主题(Topic)上,消息订阅者从主题中订阅消息。发布/订阅在一对多广播时使用。模型如图所示:
发布/订阅模型的特点:
- 每条消息都可以有多个消费者
- 针对某个Topic,消息者必须订阅后才可以消费它的消息
- Topic中的消息可被重复消费,一个消费者可以多次的去消费topic里面的消息,只要这条消息没有被确认的情况下,topic里面是没有提供确认机制的。
2.2、RabbitMQ消息传递模型(路由的效果)
RabbitMQ是一种典型的点对点模型,但是RabbitMQ中可以通过设置交换器类型来实现发布订阅模型而达到广播消费的效果。
2.2.1、RabbitMQ的点对点模型
RabbitMQ中一个核心的原则是,消息不能直接投递到Queue中。Producer只能将自己的消息投递到Exchange中,由Exchange按照路由规则将消息投递到对应的Queue中。
在Consumer中,声明自己对哪个Exchange感兴趣,并将自己的Queue绑定到自己感兴趣的路由关键字上,建立相应的映射关系;第二,在Producer中,将消息投递一个Exchange中,并指明它的路由关键字。
RabbitMQ的点对点模型如下图所示:
图中两个生产者将消息发送到exchange交换器,exchange交换器根据消息的路由关键字,将消息发送到不同的队列里面。消费者从自己的队列中拉取消息,由于队列不存储已经被消费的消息,此模型中每一条消息只有一个唯一的消费者。
2.2.2 RabbitMQ的发布订阅模型
1.RabbitMQ通过exchange可以支持多订阅,当RabbitMQ需要支持多订阅时,生产者发送的消息通过路由同时写到多个Queue,不同消费者都可以消费此消息。
2.RabbitMQ的发布订阅式如下图所示:
- Consumer声明自己对多个Exchange感兴趣,并将自己的Queue绑定到自己感兴趣的Exchange上,建立相应的映射关系。
- 图中queue1和queue2同时都与exchange1、exchange2建立映射关系。当生产者将消息发送到exchange1,exchange1会把同一份消息分别发送到queue1和queue2。同理exchange2也会把同一份消息分别发送给queue1和queue2。从而实现了同一份消息可以被多个消费者消费,消费者分别从自己的队列中拉取消息进行消费。
- 由于queue中的消息消费完后立即删除,不保留历史消息。所以在多订阅时,消息会以拷贝的形式存在不同的队列中。
3.RabbitMQ消息模型的特点:
- 通exchange交换器和消息拷贝实现多订阅。
- RabbitMQ既支持内存队列也支持持久化队列。
- 消费端为推模型,消费状态和订阅关系由服务端负责维护。
三、AMQP 模型简介
RabbitMQ是AMQP协议的一个开源实现,其内部模型实际上也是 AMQP的内部模型,如下图所示:
AMQP模型的工作流程如下:消息(Message) 被发布者 (publisher) 发送给交换机(exchange),交换机常常被比喻成邮局或者邮箱,然后交换机将收到的消息根据路由规则分发给绑定的队列(queue),最后AMQP代理会将消息投递给订阅此队列的消费者,或者消费者按照需求从队列中拉取消息。
由于网络的不可靠,接收消息的应用也有可能在处理消息的时候失败,基于此原因,AMQP模型中有一个消息确认的概念:当一个消息从队列中投递给消费者后,消息者会通知一下消息代理(Broker),这个可以是自动的也可以是手动的。当"消息确认"被启用的时候,消息代理不会完全将消息从队列中删除,直到它收到来自消费者的确认回执(ACK)。
在AMQP中,为什么不直接将消息传到队列中,而是先通过 Exchange转发呢?
AMQP协议中的核心思想就是生产者和消息者隔离,生产者从不直接将消息发送给队列。生产者通常不知道是否一个消息会被发送到队列中,只是将消息发送到一个交换机。先由 Exchange 来接收,然后 Exchange 按照特定的路由规则转发到 Queue 进行存储。