AMQP协议

AMQP协议

1. AMQP协议发展史
消息队列(Message Queue)起源于一位来自 MIT 的硬件设计教育工作者 Vivek Ranadivé 设想了一种通用软件总线,就像主板上的总线那样,供其他应用程序接入。Vivek在1983年成立了 Teknekron,高盛等公司作为第一批用户再金融交易中采用了 Teknekron的软件,同时还诞生了第一代消息队列软件:Teknekron 的 The Information Bus(TIB)。
​ Teknekron 的 TIB 允许应用开发者建立一系列规则去描述消息内容,只要消息按照这些规则发布出去,任何消费者应用都可以订阅感兴趣的内容,信息的生产者和消费者完全解耦,并且可以再传输过程中灵活混合。这个特性引起了电信特别是新闻机构的注意。1994年路透社收购了 Teknekron 。
​由于消息队列再金融交易中应用的反响,BIM 在1990年也开始研发自己的消息队列软件(BIM MQ),并且逐步演化成 WebSphere MQ 并统治着商业消息队列平台市场。同时微软开发了Microsoft Message Queue(MSMQ)。然而这些商业MQ问题在供应商壁垒,各个厂商的 MQ 之间无法互通。为了解决这个问题,Java Message Service(JMS)在2001年诞生了,试图通过提供公共 Java API的方式隐藏MQ各个供应商提供的实际接口,从而跨越壁垒和解决互通问题,但是由于使用单独的标准化接口来胶合众多不同的接口使应用程序反而变得更加脆弱。
​ 2004年 JPMorgan Chase 和 iMatix 公司一起合作开发 Advanced Message Queuing Protocol (AMQP,高级消息队列协议),从一开始就设计成为开放标准,任何人都可以执行这一标准,针对该标准任何人都可以和任何 AMQP 供应商提供的 MQ 服务器进行交互。
2. AMQP协议详解
AMQP,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件同产品,不同的开发语言等条件的限制。
AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。
AMQP在消息提供者和客户端的行为进行了强制规定,使得不同卖商之间真正实现了互操作能力。
JMS是早期消息中间件进行标准化的一个尝试,它仅仅是在API级进行了规范,离创建互操作能力还差很远。
与JMS不同,AMQP是一个Wire级的协议,它描述了在网络上传输的数据的格式,以字节为流。因此任何遵守此数据格式的工具,其创建和解释消息,都能与其他兼容工具进行互操作。
AMQP规范的版本:
0-8 是2006年6月发布
0-9 于2006年12月发布
0-9-1 于2008年11月发布
0-10 于2009年下半年发布
1.0 draft (文档还是草案)
从整体来看,AMQP协议可划分为三层,如下图所示:
这里写图片描述
这种分层架构类似于OSI网络协议,可替换各层实现而不影响与其它层的交互。AMQP定义了合适的服务器端域模型,用于规范服务器的行为(AMQP服务器端可称为broker)。在这里Model层决定这些基本域模型所产生的行为,这种行为在AMQP中用”command”表示,在后文中会着重来分析这些域模型。Session层定义客户端与broker之间的通信(通信双方都是一个peer,可互称做partner),为command的可靠传输提供保障。Transport层专注于数据传送,并与Session保持交互,接受上层的数据,组装成二进制流,传送到receiver后再解析数据,交付给Session层。Session层需要Transport层完成网络异常情况的汇报,顺序传送command等工作。
AMQP 模型设计驱动基于如下要求:
​(1)保证基于模型实现的应用之间相互可以联通;
​(2)提供对服务质量的可靠控制;
(3)命名规划,要求命名明确且保持一致;
(4)允许通过协议配置服务器连接;
(5)功能层命名能够简单的映射到应用程序级别的 API;
(6)职责单一明确,每个操作只做一件事情。
AMQP 传输层设计驱动基于如下要求:
(1)使用二进制数据流压缩和解压,提高效率;
(2)可以处理任意大小的消息,且不做任何限制;
(3)单个连接支持多个通信通道;
(4)客户端和服务端基于长链接实现,且无特殊限制;
(5)允许异步指令基于管道通信;
(6)易扩展,基于新的需求和变化支持扩展;
(7)新版本向下兼容老版本;
(8)基于断言模型,异常可以快速定位修复;
(9)对编程语言保持中立;
(10)适应代码发展演变;
3. AMQP 通信组件
3.1. AMQ Model 架构
这里写图片描述
AMQ 作为中间层服务,把消息生产和消费分隔开来,当消息生产者出现异常,不影响消费者对消息的消费,当消费者异常时,生产者生产的消息可以存放到服务的内存或者磁盘,不会影响到消费的速率,同时,消息也可以基于路由的规则可以投递到指定的消费者消费。
​ AMQ 基于模块化通过 Exchange 和 Message Queue 两个组建组合实现消息路由分发:
Exchange:
基于消息生产者和路由规则可以将消息投递到指定的 Message Queue;
Message Queue:
能够将发送过来的消息进行存储,同时将消息转发给消费者;
​ Exchange 和 Message Queue之间存在绑定关系,消息到了 Exchange 后基于路由策略可以将消息投递到已绑定且符合路由策略的 Message Queue
3.1.1 Message Queue
​消息队列会将消息存储到内存或者磁盘中,并将这些消息按照一定顺序转发给一个或者多个消费者,每个消息队列都是独立隔离的,相互不影响。
​消息队列具有不同的属性:私有,共享,持久化,临时,客户端定义或者服务端定义等,可以基于实际需求选择对应的类型,以 RabbitMQ 队列特性为例:
共享持久化消息队列:将发送的消息存储到磁盘,然后将消息转发给订阅该队列的所有消费者;
私有临时消息队列:RabbitMQ 支持 rpc 调用,再调用过程中消费者都会临时生成一个消息队列,只有当前消费者可见,且由服务端生成,调用完就会销毁队列。
3.1.2 Exchange
​交换机收到生产者投递的消息,基于路由规则及队列绑定关系匹配到投递对应的交换机或者队列进行分发,交换机不存储消息,只做转发。
AMQP定义了许多标准交换类型,基本涵盖了消息传递所需的路由类型,一般AMQP服务器都会提供默认的交换机基于交换机类型命名,AMQP的应用程序也可以创建自己的交换机用于绑定指定的消息队列发布消息。
3.1.3 消息的流转过程
这里写图片描述
消息生命周期
​消息主要由属性及消息内容组成,生产者创建消息时可以给消息设置属性及消息内容,同时也可以标记路由信息在消息上,可以将消息发送到指定交换机。
​当消息到达交换机时,交换机会基于路由规则判断消息能否转发,如果不能转发会丢弃消息同时反馈给生产者。
交换机基于路由规则可以将消息投递到一个或者多个消息队列,服务器通过复制或者计数器的方式将消息保存到不同队列中,每个队列中的消息内容是相同的,但是操作是隔离的,相互不影响。
​当消息到达消息队列后,消息队列会基于AMQP协议投递给消费者,如果无法投递给消费者或者没有消费者,消息将在内存或者磁盘中存储,等待消费者。
​当消息队列可以将消息传递给消费者时,消息将从其内部缓冲区中删除。 删除操作可能立刻执行也可以再消费者确认消息消费后再执行,删除策略消费者可以选择。
生产消息投递确认和消费消息消费确认可以作为两个事务,然后提交或者回滚事务。
3.2 AMQP 指令架构
3.2.1 协议指令(类和方法)
​作为消息中间件传统的API定义的操作非常复杂,为了解决这个问题 AMQP 基于传统 API 的功能,定义方法来对应实现API的操作每个方法只完成一件事,通过方法之间的组合来实现完整的功能,所以AMQP 形成了一个非常庞大的指令集,但是指令集中的方法都是便于理解的。
​AMQP指令集中指令,基于对应的特定功能域被划分为不同的类,其中有一些类作为特定类的支持类,属于可选的。
有如下两个场景:
同步请求:
​ 一边等待对方发送请求,一边等待对方发送回复。适用于对性能要求不高的场景。
异步请求:
​ 发送请求后不等待回复,使用场景对性能要求比较高的场景。
​为了简化指令处理,我们给每个同步请求定义不同的回复指令,也就是说同一个回复指令不可能返回给2个不同的请求。这也意味着发送同步请求的发送方可以接受和处理回复的指令,知道获得有效的同步回复指令为止。这种方式可以将 AMQP 与传统的 RPC 协议区分开来。
​一条指令可以被定义为同步请求,同步回复(针对特定请求)或者异步回复,但是每种指令真正再被定义是在客户端(即服务器到客户端)或者服务端(即户端到服务器)。
3.2.2 AMQP 映射到中间层 API
AMQP 映射到中间层 API,这个映射过程并不是所有方法和参数完全映射,因为有部分方法或者参数对应用程序没有意义。同时映射规则也是固定的,基于已定的一些规则,所有方法按照这个规则映射,不需要人工干预。
例如:队列声明方法:

Queue.Declare 
    queue=my.queue
    auto-delete=TRUE 
    exclusive=FALSE

可以作为一条线性记录
+——–+———+———-+———–+———–+
| Queue | Declare | my.queue | 1 | 0 |
+——–+———+———-+———–+———–+
class method name auto-delete exclusive
也可以作为高级 API

queue_declare (session, "my.queue", TRUE, FALSE);

​ 对于大多数应用程序来说,中间层(指令层)隐藏再技术层面,应用程序实际使用的 API 功能对比中间层相对会较少。
3.3. AMQP 传输层架构
3.3.1 简要概述
​AMQP 传输基于二进制协议,传输的信息被组织成各种类型的帧,帧携带协议方法和其他相关信息,所有的帧具有相同个格式:帧头,有效内容,帧尾。帧的有效内容格式取决于帧的类型。
假设再一个可靠的面向流的网络传输层(例如:TCP / IP)
​在一个 Socket 连接中,可以有多个独立的线程访问,这种情况就是上文中提到的 Channel(通道),每个帧都有一个属于自己的通道号码,再同一个连接中所有的帧混合在一起,不同的通道共享连接,但是针对每个通道自身的帧都是按照严格的顺序运行。
​由于帧的有效内容都是由帧头和帧尾包装,所以对应帧数据的解析是相当简单便捷的,同时基于协议规范生成帧数据也是非常容易。
3.3.2 数据类型
AMQP 使用的数据类型如下:
Integers(数值范围1-8, 8个字节):用于表示大小,数量,限制等,整数类型无符号的,可以在帧内不对齐。
Bits(统一为8个字节):用于表示开/关值。
Short strings:用于保存简短的文本属性,字符串个数限制为255,8个字节
Long strings:用于保存二进制数据块。
Field tables:包含键值对,字段值一般为字符串,整数等。
3.3.3 协议协商
​ AMQP 客户端和服务器存在协商协议。这意味着当客户端连接时,服务端会提出一些客户端可以接受或者修改的选项,如果双方达成一致,连接继续,基于协商协议,可以设定好一些先决条件。
在AMQP中,协商协议的一些具体方面:
实际的协议和版本。服务器可以在同一端口上监听多个协议。
加密参数和双方的身份验证。
最大帧大小,通道数量和其他操作限制。
4. AMQP的实现
1)OpenAMQ
AMQP的开源实现,用C语言编写,运行于Linux、AIX、Solaris、Windows、OpenVMS。
2)Apache Qpid
Apache的开源项目,支持C++、Ruby、Java、JMS、Python和.NET。
3)Redhat Enterprise MRG
实现了AMQP的最新版本0-10,提供了丰富的特征集,比如完全管理、联合、Active-Active集群,有Web控制台,还有许多企业级特征,客户端支持C++、Ruby、Java、JMS、Python和.NET。
4)RabbitMQ
一个独立的开源实现,服务器端用Erlang语言编写,支持多种客户端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。RabbitMQ发布在Ubuntu、FreeBSD平台。
5)AMQP Infrastructure
Linux下,包括Broker、管理工具、Agent和客户端。
6)ØMQ
一个高性能的消息平台,在分布式消息网络可作为兼容AMQP的Broker节点,绑定了多种语言,包括Python、C、C++、Lisp、Ruby等。
7)Zyre
是一个Broker,实现了RestMS协议和AMQP协议,提供了RESTful HTTP访问网络AMQP的能力。
5. JMS协议介绍
JMS(Java Messaging Service)是Java平台上有关面向消息中间件的技术规范,它便于消息系统中的Java应用程序进行消息交换,并且通过提供标准的产生、发送、接收消息的接口简化企业应用的开发。
JMS本身只定义了一系列的接口规范,是一种与厂商无关的 API,用来访问消息收发系统。它类似于 JDBC(Java Database Connectivity):这里,JDBC 是可以用来访问许多不同关系数据库的 API,而 JMS 则提供同样与厂商无关的访问方法,以访问消息收发服务。许多厂商目前都支持 JMS,包括 IBM 的 MQSeries、BEA的 Weblogic JMS service和 Progress 的 SonicMQ,这只是几个例子。 JMS 使您能够通过消息收发服务(有时称为消息中介程序或路由器)从一个 JMS 客户机向另一个 JML 客户机发送消息。消息是 JMS 中的一种类型对象,由两部分组成:报头和消息主体。报头由路由信息以及有关该消息的元数据组成。消息主体则携带着应用程序的数据或有效负载。根据有效负载 的类型来划分,可以将消息分为几种类型,它们分别携带:简单文本 (TextMessage)、可序列化的对象 (ObjectMessage)、属性集合 (MapMessage)、字节流 (BytesMessage)、原始值流 (StreamMessage),还有无有效负载的消息 (Message)。
6. STOMP协议介绍
STOMP,Streaming Text Orientated Message Protocol,是流文本定向消息协议,是一种为MOM(Message Oriented Middleware,面向消息的中间件)设计的简单文本协议。
它提供了一个可互操作的连接格式,允许STOMP客户端与任意STOMP消息代理(Broker)进行交互,类似于OpenWire(一种二进制协议)。
由于其设计简单,很容易开发客户端,因此在多种语言和多种平台上得到广泛应用。其中最流行的STOMP消息代理是Apache ActiveMQ。
STOMP协议工作于TCP协议之上,使用了下列命令:
* SEND 发送
* SUBSCRIBE 订阅
* UNSUBSCRIBE 退订
* BEGIN 开始
* COMMIT 提交
* ABORT 取消
* ACK 确认
* DISCONNECT 断开
7.消息中间件概况
消息队列技术是分布式应用间交换信息的一种技术。消息队列可驻留在内存或磁盘上,队列存储消息直到它们被应用程序读走。通过消息队列,应用程序可独立地执行–它们不需要知道彼此的位置、或在继续执行前不需要等待接收程序接收此消息。
在分布式计算环境中,为了集成分布式应用,开发者需要对异构网络环境下的分布式应用提供有效的通信手段。为了管理需要共享的信息,对应用提供公共的信息交换机制是重要的。
设计分布式应用的方法主要有:远程过程调用(PRC)-分布式计算环境(DCE)的基础标准成分之一;对象事务监控(OTM)-基于CORBA的面向对象工业标准与事务处理(TP)监控技术的组合;消息队列(MessageQueue)-构造分布式应用的松耦合方法。
(a) 分布计算环境/远程过程调用 (DCE/RPC)
RPC是DCE的成分,是一个由开放软件基金会(OSF)发布的应用集成的软件标准。RPC模仿一个程序用函数引用来引用另一程序的传统程序设计方法,此引用是过程调用的形式,一旦被调用,程序的控制则转向被调用程序。
在RPC 实现时,被调用过程可在本地或远地的另一系统中驻留并在执行。当被调用程序完成处理输入数据,结果放在过程调用的返回变量中返回到调用程序。RPC完成后程序控制则立即返回到调用程序。因此RPC模仿子程序的调用/返回结构,它仅提供了Client(调用程序)和Server(被调用过程)间的同步数据交换。
(b) 对象事务监控 (OTM)
基于CORBA的面向对象工业标准与事务处理(TP)监控技术的组合,在CORBA规范中定义了:使用面向对象技术和方法的体系结构;公共的 Client/Server程序设计接口;多平台间传输和翻译数据的指导方针;开发分布式应用接口的语言(IDL)等,并为构造分布的 Client/Server应用提供了广泛及一致的模式。
(c) 消息队列 (Message Queue)
消息队列为构造以同步或异步方式实现的分布式应用提供了松耦合方法。消息队列的API调用被嵌入到新的或现存的应用中,通过消息发送到内存或基于磁盘的队列或从它读出而提供信息交换。消息队列可用在应用中以执行多种功能,比如要求服务、交换信息或异步处理等。
中间件是一种独立的系统软件或服务程序,分布式应用系统借助这种软件在不同的技术之间共享资源,管理计算资源和网络通讯。它在计算机系统中是一个关键软件,它能实现应用的互连和互操作性,能保证系统的安全、可靠、高效的运行。中间件位于用户应用和操作系统及网络软件之间,它为应用提供了公用的通信手段,并且独立于网络和操作系统。中间件为开发者提供了公用于所有环境的应用程序接口,当应用程序中嵌入其函数调用,它便可利用其运行的特定操作系统和网络环境的功能,为应用执行通信功能。
如果没有消息中间件完成信息交换,应用开发者为了传输数据,必须要学会如何用网络和操作系统软件的功能,编写相应的应用程序来发送和接收信息,且交换信息没有标准方法,每个应用必须进行特定的编程从而和多平台、不同环境下的一个或多个应用通信。例如,为了实现网络上不同主机系统间的通信,将要求具备在网络上如何交换信息的知识(比如用TCP/IP的socket程序设计);为了实现同一主机内不同进程之间的通讯,将要求具备操作系统的消息队列或命名管道(Pipes)等知识。
目前中间件的种类很多,如交易管理中间件、面向Java应用的Web应用服务器中间件等,而消息传输中间件(MOM)是其中的一种。它简化了应用之间数据的传输,屏蔽底层异构操作系统和网络平台,提供一致的通讯标准和应用开发,确保分布式计算网络环境下可靠的、跨平台的信息传输和数据交换。它基于消息队列的存储-转发机制,并提供特有的异步传输机制,能够基于消息传输和异步事务处理实现应用整合与数据交换

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值