热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

RabbitMQ之AMQP0-9-1模型解释

本节主要叙述主题交换机可以将消息路由到一个或者多个与路由键规则匹配的消息队列,具体匹配规则以后详述类似于数据库模糊匹配规则

写在开头

本文翻译RabbitMQ官方文档属于译作(部分)详细链接

如有版权问题联系作者删除,如发现错误请不吝指出

说明

本节主要叙述 RabbitMQ 中的 AMQP 0-9-1 协议即 Advance Message Queuing Protocol - 高级消息队列协议 ,该协议是理解 RabbitMQ 消息模型的重要理论基础。

AMQP 模型和 AMQP 0-9-1 协议概览

什么是 AMQP 0-9-1

AMQP 0-9-1 是一种高级消息协议,它允许特定的客户端应用程序能够与特定的 消息代理中间件(messaging middleware brokers) 进行消息传输和交流。

消息代理中间件和其扮演的角色

中间件接收来自于消息发布者(也叫生产者,产生消息的应用程序组)传递的消息并且把它们路由给接收者(也叫消费者,处理消息的应用程序组)

由于 AMQP 0-9-1 是一种网络协议,所以 生产者、消费者、和消息代理 都可以运行在网络中不同的机器上。

AMQP 0-9-1 模型简介

AMQP 0-9-1 模型定义了如下规则

消息被发送到交换机 exchanges ,而后交换机利用绑定规则 bindings 将消息副本发布到消息队列 queue ,然后消息队列中的消息,要么被传递给了订阅消息队列的消费者,要么消费者按照需要从消息队列拉取 fetch/pull 消息。

RabbitMQ 之 AMQP 0-9-1 模型解释

当一条消息发布的时候,发布者可能会指定一些消息属性 message attributes(也叫message meta-data消息元数据) ,其中有一些消息属性是用于消息中间件处理消息,其余的部分则是用于消息消费者对于消息中间件完全透明。

由于网络的不稳定性,消息在传输过程中可能出现失败的情况,鉴于此 AMQP 0-9-1 提供了一种消息确认机制 message acknowledgements : 当一条消息传递给消费者后该消费者发送一条通知 notifies 给消息中间件来确认消息,无论是自动的还是开发者自己这样做,当消息确认机制使用时,只有当消息代理收到通知后才会将该条或该组消息从消息队列中移除。

在一些特定情况下,比如当消息不能被路由时,消息可能会被返回给消息发布者,或者删除,或者如果消息代理实现了某种扩展插件,则这些无法被路由的消息可能会被放入一个称之为 dead letter queue (死亡标记队列)的队列中,发布者可以通过指定一些确定的 消息属性 message attributes 来响应出现这种情景时消息应该如何被处理。

exchange、bindings、queue 均被称为 AMQP实体-AMQP entities

AMQP是一种可编程的协议

AMQP 0-9-1 是一种可编程协议,实体和路由规则应该被实现该协议的应用来定义。协议只是为具体操作提供一种处理的规范,具体实现( exchange和queue如何路由,如何定制绑定规则等

)应该有具体应用来完成。

这种方式给了开发者很大的自由空间,但是也需要他们能意识到可能潜在的定义冲突,实际上定义冲突很少见,大多都由错误的设定引起。

交换机和交换机的类型

交换机 exchangesAMQP 0-9-1 协议定义的消息应该被送达的实体。交换机拿到消息并且将它路由到一个或者多个队列中去,具体的路由算法由交换机的种类决定。交换机类型和路由规则被统称为 (binding) 绑定规则(交换机和消息队列间的绑定规则), AMQP 0-9-1 代理提供了四种交换机类型

名称 默认预定义名称
Direct exchange (Empty string) and amq.direct
Fanout exchange amq.fanout
Topic exchange amq.topic
Headers exchange amq.match (and amq.headers in RabbitMQ)

除了交换机类型以外,交换机还定义了一些属性,其中最重要的属性如下:

  • Name 名称
  • Durability 持续性(控制交换机能从在重启后恢复)
  • Auto-delete 交换机在最后一条消息出栈之后是否删除
  • Arguments 参数,可选用于插件或者消息代理的一些特殊用途

交换机可以是持续性的也可以是瞬态的,持续性的交换机可以在重启后恢复,而瞬态的交换机则需要重新定义。

Default exchange/默认交换机

默认交换机是被消息代理预定义的没有名称的直转交换机 Direct exchange也有叫直连交换机 他有一个特殊属性使得它非常有用,每一个创建的消息队列都会使用队列的名称绑定路由键 routing key 来和默认交换机绑定。

比如当你定义了一个名为 search_index_online 的消息队列时,队列会使用 search_index_online 自动绑定到默认交换机,消息发布者可以使用默认的交换机附带 search_index_online 的路由键来发送消息到消息队列,看起来没有定义任何交换机,像是直接将消息传递给了队列。

Direct exchange/直转交换机/直连交换机

直转交换机基于路由键 routing key 给消息队列转发消息,直转交换机可用于消息单播(尽管实际上可以用于多播消息)直转交换机模式如下

  • 消息队列通过路由键K与交换机绑定
  • 当交换机收到一个需要转发到路由键等于R的消息队列时,如果K=R,则交换机将消息发送给消息队列

直转交换机通常用于任务分发,但在使用时必须注意,在 AMQP 0-9-1 协议中消费者之间才有负载均衡,而不是消息队列之间。直转路由过程如下

RabbitMQ 之 AMQP 0-9-1 模型解释

Fanout Exchange/扇面交换机

扇面交换机是一种多播交换机,会将消息路由到所有绑定到该交换机上的消息队列,并且会忽略路由键,如果有N个消息队列绑定到该交换机上,则交换机会将消息副本传递给每一个绑定到上面的消息队列,扇面交换机的应用场景

  • 大量多用户在线游戏,可以将消息广播给所有人比如流行游戏吃鸡,全员广播时很切合此类业务需求。
  • 体育新闻类场景,可以利用扇面交换机将最新分数以及信息广播到所有手机端

扇面交换机图示如下

RabbitMQ 之 AMQP 0-9-1 模型解释

Topic Exchange / 主题交换机

主题交换机可以将消息路由到一个或者多个与路由键规则匹配的消息队列,具体匹配规则以后详述类似于数据库模糊匹配规则

Header Exchange / 头部交换机

头部交换机会根据 消息指定的头部信息将消息路由到不同的消息队列,头部交换机会忽略路由键,取而代之的是使用头部信息来判断路由地址

消息可以指定一组或者多组头部信息用于头部交换机匹配消息队列,我们可以使用 x-match 头来指定满足任意一组还是必须所有满足才能将消息传递给消息队列 x ,可以选 any/all

需要注意的是在交换机中以 x- 开头的头部将不会参与解析。

Queue / 队列

队列用于储存消息,和其他消息系统和任务系统大致相同,队列和交换机共享一些属性,也定了一些额外的属性

  • Name
  • Durable 当一个代理重启之后是否会恢复
  • Exclusive 独占,只维持一个链接,当链接关闭后,该队列是否会被删除
  • Auto-delete 至少有一个订阅者,当最后一个订阅者取销订阅之后,是否会被删除
  • Arguments 额外属性,一般用于消息代理

要使用一个队列必须声明队列,在声明队列时如果队列已经存在并且声明的队列和已存在队列的属性不一致时会抛出一个通道级别的异常 PRECONDITION_FAILED 不满足前提条件

Queue Name

应用程序可以自己指定一个队列名称,也可以让消息代理生成一个名称,队列名称最多为255位的 UTF-8 字符集, AMQP 0-9-1 代理可以自动生成队列名称,要使用这一特性只需传入一个空的名称,代理会返回创建的队列名称。

amq. 开头的队列名称是消息代理内部使用的,当应用创建这类名称的队列时,会抛出 ACCESS_REFUSED 异常

Queue Durability / 队列持续性

持续性的队列将会被持久化的磁盘中,当消息代理重启之后,被持久化的队列将会被重新声明, 但只有持久化的消息才会被恢复 队列持久化和消息持久化是彼此独立的。

Bindings / 绑定

绑定是交换机将消息路由到队列所使用的规则

Consumers / 消费者

在队列中保存消息是无意义,只有当消息能够被应用消费时才有意义在 AMQP 0-9-1 协议模型中消费者有两种方式获得队列中的消息

push API
pull API

push api 模式下,消费者必须标明对某种类型的消息有兴趣,此种情况也叫 注册一个消费者或者订阅一个主题 当然可能完全可能存在不止一个消费者订阅了某一个消息队列,每一个消费者都有一个标识符叫 consumer tag 消费标签,消费标签是一串字符串,可以用来退订消息队列。

Message Acknowledgements / 消息确认

当消费者接收和处理一个消息时有可能出现一些意外情况,比如消息无法处理,或者消费应用程序由于某些原因崩溃亦有甚者由于网络原因导致接收到的消息产生问题。这种情景下就产生了一个问题!? AMQP 代理该什么时候从队列里将这些消息删除呢? AMQP 0-9-1 规范推荐两种选择

  • 在代理将消息发送给消费者之后(不管是使用 basic.deliver 还是使用 basic.get-ok 这两个 AMQP 方法)
  • 在消费者返回一个确认标记后(使用 basic.ack - AMQP 方法)

前一种称之为 自动确认模型 ,后一种称为 显示确认模型显示确认模型 的情况下,消费者应用可以控制何时发送确认标记,可以是在收到消息后,也可以是在消息处理完成或者被保存之后,或者对消息的处理全部完成之后。

如果一个消费者由于宕机或者崩溃没有返回确认标记,那么消息队列将重发该消息到另外的消费者应用,如果没有消费者应用程序订阅到该消息队列,那么消息队列将会等到有消费者订阅之后,再将消息重新传递给消费者。

Rejecting Messages / 拒绝消息

消费者在处理消息时可能成功也可能失败,当消费者处理消息失败时,消费者可以通过拒绝一个消息来表明消息处理失败,此种情况下,消费者应用可以指示消息代理丢弃或者重新入队消息,当只有一个消息队列或者只有一个消费者时需要防止 消息的无限循环(拒绝-重入队列-拒绝-重入队列....)

Negative Acknowledgements / 消极确认

AMQP 0-9-1 模型下 basic.reject 只能拒绝单条消息,如果使用RabbitMQ的话,RabbitMQ提供了一个扩展叫 消极确认 也叫 nacks ,要拒绝多条消息可以设置 multiple = true 详情 点我

Prefetching Message / 预取消息

当多个消费者订阅一个消息队列时,如果能在下次发送确认标记之前指定每一个消费者可以接收多少条消息,这将非常有用,因为者可以用于实现简单的负载均衡或在消息生产者批量发布消息时提高吞吐量,要注意的是RabbitMQ仅支持管道级别的预取计数 prefetch-count 而非基于链接 connection 或者大小 size 的预取

Message Attributes and Payload / 消息属性和负载

AMQP 模型下消息是有属性的,有一些属性是 AMQP 0-9-1 规范定义的,下面是一些例子

  • Content type 文档类型
  • Content encoding 文档编码
  • Routing key 路由键
  • Delivery mode (persistent or not) 交付模式 - 持久化/不持久化
  • Message priority 消息优先级
  • Message publishing timestamp 消息发布时间
  • Expiration period 过期周期
  • Publisher application id 发布应用id

除此之外消息还有一个负载 payload(消息携带的数据) ,该负载对 AMQP 协议是不透明的,对消息来讲负载可有可无,在负载区应该存放序列化数据如 JSON、Thrift、Protocol Buffers and MessagePack 使用的文档类型和编码应该在 content-typecontent-encoding 中指定

消息的持久化需要消息自己指定持久化模型,当消息需要持久化时,消息将会被保存到磁盘中,当消息代理重启后,这些消息将会被恢复,但是消息持久化会影响性能。

Virtual Hosts / 虚拟主机

为了能使单个消息代理能够承载多套独立的环境(用户组,交换机组,消息队列等都成套独立)所以 AMQP 有了虚拟主机的概念,就像多个web应用使用虚拟主机一样,彼此之间完全独立,每套虚拟主机里面都包含其 exchange,queue,consumer,publisher 等。

写到最后

该文档是我翻译的RabbitMQ官方文档,其间肯定存在诸多的不足和有误之处,若有人发现错误请及时与我联系修改,谢谢。


以上所述就是小编给大家介绍的《RabbitMQ 之 AMQP 0-9-1 模型解释》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 我们 的支持!


推荐阅读
  • C语言注释工具及快捷键,删除C语言注释工具的实现思路
    本文介绍了C语言中注释的两种方式以及注释的作用,提供了删除C语言注释的工具实现思路,并分享了C语言中注释的快捷键操作方法。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文介绍了OpenStack的逻辑概念以及其构成简介,包括了软件开源项目、基础设施资源管理平台、三大核心组件等内容。同时还介绍了Horizon(UI模块)等相关信息。 ... [详细]
  • 实现一个通讯录系统,可添加、删除、修改、查找、显示、清空、排序通讯录信息
    本文介绍了如何实现一个通讯录系统,该系统可以实现添加、删除、修改、查找、显示、清空、排序通讯录信息的功能。通过定义结构体LINK和PEOPLE来存储通讯录信息,使用相关函数来实现各项功能。详细介绍了每个功能的实现方法。 ... [详细]
  • 本文介绍了Foundation框架中一些常用的结构体和类,包括表示范围作用的NSRange结构体的创建方式,处理几何图形的数据类型NSPoint和NSSize,以及由点和大小复合而成的矩形数据类型NSRect。同时还介绍了创建这些数据类型的方法,以及字符串类NSString的使用方法。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 关于我们EMQ是一家全球领先的开源物联网基础设施软件供应商,服务新产业周期的IoT&5G、边缘计算与云计算市场,交付全球领先的开源物联网消息服务器和流处理数据 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Python爬虫中使用正则表达式的方法和注意事项
    本文介绍了在Python爬虫中使用正则表达式的方法和注意事项。首先解释了爬虫的四个主要步骤,并强调了正则表达式在数据处理中的重要性。然后详细介绍了正则表达式的概念和用法,包括检索、替换和过滤文本的功能。同时提到了re模块是Python内置的用于处理正则表达式的模块,并给出了使用正则表达式时需要注意的特殊字符转义和原始字符串的用法。通过本文的学习,读者可以掌握在Python爬虫中使用正则表达式的技巧和方法。 ... [详细]
  • node.jsurlsearchparamsAPI哎哎哎 ... [详细]
author-avatar
呼和浩特-时尚范儿
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有