消息中间件接收应用产生的消息,然后按照一定的规则发给处理消息的应用。
既然AMQP 0-9-1是网络协议,消息生产者,消息消费者和中间件可以在不同的计算机上。
交换机是AMQP的实体,是消息被发送到的地方,交换机把一个消息路由给0个或多个队列,这个路由依赖于交换机类型和规则,称之为binding keys 。
交换机类型有四种:
Name | Default pre-declared names |
---|---|
Direct exchange | (Empty string) and amq.direct |
Fanout exchange | amq.fanout |
Topic exchange | amq.topic |
Headers exchange | amq.match (and amq.headers in RabbitMQ) |
交换机有很多属性,以下是最重要的四个:
1.Name,交换机的名字;
2.Durability,交换机的持久属性,交换机可以是临时的或者持久的,交换机是持久时,中间件重启时交换机还存在;
3.Auto-delete,当交换机的最后一个队列不和他关联,这个就交换机就会被删除;
4.Arguments,可选的,被插件和指定的中间件特性;
默认的交换机
默认的交换机就是没有名字的direct 模式的交换机,就是空字符串,被中间件预声明,它有一个特殊的属性使它得对简单的应用很适用,每个队列在创建的时候默认和默认的交换机关联,队列名和binding key(即交换机和队列之间的关联) 相同。
direct 交换机
direct交换机依赖消息的routing key来传递消息给队列,direct交换机对于消息的单播是理想的,虽然direct交换机也可以多播,下面是它如何工作的:
1.一个队列使用binding key 为K和交换机关联在一起;
2.当有routing key 为R的消息到达direct交换机,如果R=K,那么这个消息会被交换机路由到这个队列;
direct 交换机经常被用来分配任务到多个工作者(即同个应用的多个实例),以round Robin的模式,这时AMQP 0-9-1消息是被均衡的加载到消费者的,而不是队列,理解这个是很重要的。
fanout交换机
一个fanout交换机路由信息到所有与它有关的队列中,并且binding key是被忽略的,如果n个队列和某个交换机关联,当一个新消息被发布到交换机,这个消息的复制版本会被送到这n个队列,fanout交换机对于广播消息是理想的。
因为fanout交换机是传递消息的复制版本到所有与它关联的队列,所以它的应用场景很相似:
大规模多玩家在线游戏可以使用fanout交换机来做选手积分榜的更新以及游戏中的全球活动。
运动新闻网站可以在相近的时间里使用fanout交换机来推送分数的更新到移动客户端。
群聊可以使用fanout交换机在群成员之间分发消息(虽然AMQP没有内置观念,所以XMPP可能是更好地选择)
topic 交换机
topic交换机经常被用来实现多样的发布订阅模式的变化,topic交换机一般被用来多播。
无论什么时候,当一个问题涉及到消费者有选择地选择哪些消息来接收,topic交换机应该被考虑。
应用场景:
1.推送有关具体地理位置的相关数据,比如销售点
2.股价的更新
headers 交换机
暂时搞不懂,
队列
队列暂存会被应用消费的消息,队列和交换机共享一些属性,但是队列还有其他的属性:
1.持久,当中间件重启时,队列还会存在;
2.专用的,单独的,被唯一的连接使用,当连接关闭队列会被删除;
3.自动删除,当这个队列的最后一个消费者取消订阅,至少有一个消费者的队列会被删除;
4.参数,可选,被插件和指定中间件特性使用,如消息TTL,队列长度限制等
队列使用之前要被声明,如果声明的这个队列不存在,这个队列将被被创建;如果声明的这个队列已存在,并且和已存在的队列属性相同,也没有什么影响;如果声明的这个队列已存在,并且和已存在的队列属性不同,就会报channel-level exception,异常编码是406.
队列名
应用可以使用对列名或者请求中间件为他们生成一个。对列名最长是255字节的utf-8编码的字符,AMQP 0-9-1中间件能生成一个唯一的队列名代表一个应用。为了使用这一特性,传一个空的字符串作为队列名属性,被生成的对列名被返回给客户(此处不太理解)原文是,The generated name will be returned to the client with queue declaration response.
以"amq"开始的队列名是保留给中间件内部使用的,试着以这样的名字声明队列会损坏这一规则,造成channel-level exception,异常编码是403.
队列的持久化
当中间件崩溃又重启时,只有持久化的队列会被重新声明,持久化的队列并不会导致被路由到此队列的消息持久化,只有本身持久化的消息才会被恢复。
消费者
队列里的消息是无用的,除非有消费者进行处理。在AMQP 0-9-1模型中,有两种方式来获得消息:
1.让消息传递给消费者,(push API);
2.消费者自己去取消息,(puLL API);
当使用push API时,应用需要声明对某些队列消费消息的兴趣。当应用这么做的时候,我们认为应用注册了一个消费者或者仅仅是订阅了一个队列,一个队列有多个消费者,或者仅有一个是有可能的。
每个消费者有一个标识,叫做消费者标签,被用来取消消息的订阅,消费者标识就是字符串。
AMQP 0-9-1的方法
AMQP 0-9-1API的地址是点击打开链接。
connections
AMQP连接存活很长。AMQP是应用级别的协议,使用TCP来进行可靠地传递,AMQP连接使用认证并且能够用TLS来保护自己。当一个应用不再需要连接到AMQP中间件,这个应用应该优雅地关闭AMQP连接而不是突然地关闭底层的TCP连接。
channels
一些应用需要到AMQP中间件的多重连接,然而,保持多个TCP连接同时打开是不好的,因为这么做会耗费系统资源,还会使得配置防火墙更困难。AMQP 0-9-1连接使用通道来多路传输,可以认为是多个轻量级的连接共享一个TCP连接。
对于使用多线程的应用来说,每一个线程打开一个通道并且它们之间彼此不共享是很常见的。
某个通道上的交互与另一个通道的交互是完全分开的,因此每一个AMQP方法也携带一个通道号,客户端(生产者或消费者)用来辨别这个方法是哪个通道的。
virtual host
虚拟主机使一个中间件分割成多个分隔开的环境成为可能。AMQP包含虚拟主机的概念。
如果翻译的不对,恳请指正,谢谢。