关于AMQP协议

前言

最近在学习RabbitMQ,而RabbitMQ的特色之一就是AMQP协议,阅读完其英文的tutorial后,便做了笔记整理,如果有错,还希望大家能在评论区指出!

什么是AMQP协议

AMQP(Advance Message Queuing Protocol)是一个消息协议。它支持符合要求的客户端与中间件进行通信。它是RabbitMQ支持的消息队列协议之一。

AMQP特性

  • 可靠性高(持久化、消息ACK应答)
  • 可扩展性强(例如可以自定义Exchange)
  • 支持Channel
  • 支持虚拟主机

角色

  • Publisher(消息生产者)
  • Consumer(消息消费者)

架构

请添加图片描述
上图说明了一条消息从产生到消费的过程,假如一切顺利,是这样一个过程:

  • 生产者产生消息,放入MQ的Exchange中
  • Exchange根据消息的路由key,将消息发送到合适的Queue中
  • 如果有消费者注册到Queue上,那么Queue会向消费者发送消息
  • 消费者拿到消息,消费

核心——Exchange

Direct Exchange

Exchange根据key来路由消息到正确的队列中,如果与队列绑定的应用程序有多个实例,那么队列中的消息会使用轮询的方式发送到实例实现负载均衡

  • 如果在创建在推送消息时不绑定Exchange(Exchange为空字符串),则会使用默认的Exchange,默认的Exchange就是Direct Exchange,路由key就是队列名。
  • 负载均衡是在消费者之间实现的,不是在队列

请添加图片描述

Fanout Exchange

在这种交换模式下,路由key将被忽略,消息会被路由到所有与该Exchange绑定的队列中。Fanout是广播消息的理想方式。

应用场景举例:

  • 实时消息推送
  • IM群聊

请添加图片描述

Topic Exchange

在这种交换模式中,消息路由至队列,依据以下原则:

  • 路由key
  • 队列与Exchange的绑定模式

这其实就是发布/订阅模式,先由key确定推送范围,再有绑定模式确定推送给谁。在这里,队列是订阅者。

Headers Exchange

它是Direct Exchange的升级版,它不使用单个key来路由,而是使用多个属性,这些属性存在于消息的header中。在设置Header Exchange的时候可以指定是匹配一个属性就允许路由,还是说所有的属性都匹配才能进行路由。

核心——Queue

默认情况下(指我们在定义队列的时候不指定队列名),AMQP会为每一个应用程序生成唯一的队列名。

队列是支持持久化的,关于持久化,下文会进一步叙述。

amq.是一个保留字,如果使用它来定义队列,那么会报错

核心——Acknowledgements

Acknowledgements有时又称为ACK机制,是消息队列可靠性的一种表现形式,它分为

  • 客户端消费成功后返回给MQ的ACK(积极的)
  • 客户端消费失败后返回给MQ的ACK(消极的)

积极的ACK

积极的ACK又有两种模式:

  • 一种是MQ在发送消息时主动发给客户端的
  • 另一种是客户端发给MQ的

一般是使用后一种,原因是:

  • 可以自定义ACK发送的时机,是在一接收到消息就发送,还是在等消息消费成功后再发送,都由用户进行决定。
  • 假如客户端挂了,没有在指定时间内发送ACK,那么消息将不会被删除,MQ会将这条消息分发给其他的客户端(如果一个应用程序有多个实例的话),否则,MQ会等待其他客户端注册到这一个队列上后重新发送该消息。

消极的ACK

如果是客户端应用程序的原因导致的消息消费失败,客户端可以通过ACK的方式告诉MQ消息消费失败了,同时可以告诉MQ要丢弃还是重新进队列分发(Requeue),这称为拒绝消息。如果想拒绝多条消息,可以使用插件完成。

持久化

持久化也是可靠性的另一种表现形式。

Queue的持久化

在AMQP中,队列支持非持久化和持久化两种模式。在持久化模式下,队列的元数据会被写入磁盘,重启后队列还在;而在非持久化模式下,队列的元数据将会被写入内存,重启后,队列会销毁。

消息的持久化

在AMQP中,消息也有持久化与非持久化两种模式。注意,并不是把消息放入支持持久化的Exchange或Queue就可以实现,它取决于消息自身是否开启了持久化支持。

Channel与虚拟主机

channel

由于AMQP是应用层协议,底层基于TCP/IP协议,因此正常情况只能支持一个连接进行通讯。但是有的应用程序可能需要多个连接与MQ进行通讯,如果多开TCP连接,是一件很消耗资源的事。因此便有了Channel,一个Channel可以同时carry多个MQ连接,由于每一个Channel是相互隔离的,因此MQ中的操作需要带上Channel ID来识别是哪一个Channel的操作。

Channel与MQ连接强依赖,这个特性对于多线程/多进程应用程序十分有用。

虚拟主机

这个特性类似网站服务器中的虚拟主机的概念,即在一个RabbitMQ中运行多个MQ实例,它们之间相互隔离。

相关阅读

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值