“消息队列”是在消息的传输过程当中保存消息的容器。算法
“消息”是在两台计算机间传送的数据单位。消息能够很是简单,例如只包含文本字符串;也能够更复杂,可能包含嵌入对象。缓存
消息被发送到队列中。“消息队列”是在消息的传输过程当中保存消息的容器。消息队列管理器在将消息从它的源中继到它的目标时充当中间人。队列的主要目的是提供路由并保证消息的传递;若是发送消息时接收者不可用,消息队列会保留消息,直到能够成功地传递它。安全
通常的消息队列是基于生产者-消费者模型。用于实时性要求并非那么高、异步通讯的场景。服务器
AMQP(AdvancedMessageQueuingProtocal,高级消息队列协议)是一个提供统一异步消息传递服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件而设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不一样产品、不一样开发语言等条件的限制。架构
左边的客户端向右边的客户发送消息,流程以下:异步
在该模型中,三个主要功能模块链接成一个处理链完成预期的功能:ui
Exchange自己不保持消息,只是起到路由的做用,Exchange接收消息生产者(MessageProducer)发送的消息根据不一样的路由算法将消息发送往MessageQueue。MessageQueue会在消息不能被正常消费时缓存这些消息,具体的缓存策略由实现者决定,当MessageQueue与消息消费者(Messageconsumer)之间的链接通畅时,MessageQueue会将消息转发到consumer。spa
一个Broker(AMQP服务器)中会存在多个MessageQueue?Exchange怎样知道它要把消息发送到哪一个MessageQueue中去呢?图8-1中的Binding就是经过绑定Exchange与MessageQueue来解决这个问题。消息应用者(ClientApplication)控制Exchange与某个特定MessageQueue绑定,并将这个MessageQueue接受何种特定消息的条件绑定到Exchange,这个条件也叫Bindingkey或Criteria。AMQP协议的架构以下图示意。设计
该图(VirtualHost)用来指Exchange和MessageQueue组成的集合。它是一个虚拟概念,一个虚拟主机能够是一台服务器,还能够是由多台服务器组成的集群,还能够是一些虚拟机组成的集群,上面运行一些Exchange和MessageQueue。
下面详细解释一下AMQP的工做原理:3d
从上图看,Message是AMQP所操纵的基本单位,它由Producer产生,通过Broker被Consumer所消费。它的基本结构有两部分:Header和Body。Header是由Producer添加上的各类属性的集合,这些属性有:控制Message是否可被缓存,接收的Queue是哪一个,优先级是多少等。Body是真正须要传送的数据,它是对Broker不可见的二进制数据流,在传输过程当中不该该受到影响。
一个Exchange在与多个MessageQueue经过绑定后,Exchange中就会存在一个路由表,这个表中存储着每一个MessageQueue所须要消息的限制条件。Exchange就会检查它接收到的每一个Message的Header及Body信息,来决定将Message路由到哪一个Queue中去。每一个Message的Header中应该有个属性叫RoutingKey,它由Message发送者产生,提供给Exchange路由这条信息的标准。Exchange根据不一样路由算法有不一样有ExchangeType。
这些基础的路由算法由AMQP提供,固然ClientApplication也能够自定义各类本身的扩展路由算法。
当Exchange按照必定的路由算法把消息发到MessageQueue后,做为消息的存储和分发实体,MessageQueue会把消息缓存到内存或硬盘中,而且按照顺序把这些消息发给一个或者多个消息的消费者。
OpenStack遵循这样的设计原则:项目之间经过RESTful API进行通讯;项目内部,不一样服务进程之间的通讯,则必需要经过消息总线。这种设计思想保证了各个项目对外提供服务的接口能够被不一样类型的客户端高效支持,同时也保证了项目内部通讯接口的可扩展性和可靠性,以支持大规模的部署。
软件从最初的面向过程,面向对象,再到面向服务(SOA),要求咱们去考虑各个服务之间如何传递消息。借鉴硬件总线的概念,消息总线的模式被引入,顾名思义,一些服务向总线发送消息,其余服务从总线上获取消息。
OpenStack oslo.messageing库实现了如下两种方式来完成项目内部各服务进程之间的通讯:
经过远程过程调用,一个服务进程能够调用其余远程服务进程方法,而且有两种调用方式:call和cast。call 则是同步执行的,调用者会被阻塞直到结果返回;cast 则是异步执行,结果不会马上被返回,调用者也不会被阻塞,可是调用者须要利用其余方式查询此次远程调用的结果。
某个服务进程能够把事件通知发送到消息总线上,该消息总线上全部对此类事件感兴趣的服务进程,均可以得到此事件通知并进行一步的处理,处理的结果并不会返回给事件发送者。这种通讯方式,不但能够在同一个项目内部的各个服务进程之间发送通知,也能够实现跨项目之间的通知发送。Ceilometer就经过这种方式大量获取其余OpenStack项目的事件通知,从而进行计量和监控。
OpenStack中所支持的消息总线类型中,大部分都是基于AMQP的。前面已经提到过了,故不赘述。
配图解释:
对于MQ中的概念进行了简单的介绍。以后还会进行必定的扩充——好比在一些常见应用中MQ的应用。