rabbitmq
使用场景
数据投递,非阻塞操作或推送通知。或许你想要实现发布/订阅,异步处理,或者工作队列
特性
持久性机制、投递确认、发布者证实和高可用性机制
路由
消息在到达队列前是通过交换机进行路由的
协议
支持多种消息协议的消息传递
发布者指定属性发送到交换机
交换机发送到队列
消费者从队列消费或者拉取
开启ack
死信队列
交换机状态:持久,暂存
默认交换机(没有名字的直连交换机)
每个新建队列(queue)都会自动绑定到默认交换机上,绑定的路由键(routing key)名称与队列名称相同
直连型交换机
直连型交换机(direct exchange)是根据消息携带的路由键(routing key)将消息投递给对应队列的
直连交换机用来处理消息的单播路由(unicast routing)(尽管它也可以处理多播路由)
直连交换机经常用来循环分发任务给多个工作者
扇型交换机
扇型交换机(funout exchange)将消息路由给绑定到它身上的所有队列,而不理会绑定的路由键
扇型用来交换机处理消息的广播路由(broadcast routing)
应用案例
大规模多用户在线(MMO)游戏可以使用它来处理排行榜更新等全局事件
体育新闻网站可以用它来近乎实时地将比分更新分发给移动客户端
分发系统使用它来广播各种状态和配置更新
在群聊的时候,它被用来分发消息给参与群聊的用户。(AMQP没有内置presence的概念,因此XMPP可能会是个更好的选择)
主题交换机
主题交换机(topic exchanges)通过对消息的路由键和队列到交换机的绑定模式之间的匹配,将消息路由给一个或多个队列。主题交换机经常用来实现各种分发/订阅模式及其变种
应用案例
分发有关于特定地理位置的数据,例如销售点
由多个工作者(workers)完成的后台任务,每个工作者负责处理某些特定的任务
股票价格更新(以及其他类型的金融数据更新)
涉及到分类或者标签的新闻更新(例如,针对特定的运动项目或者队伍)
云端的不同种类服务的协调
分布式架构/基于系统的软件封装,其中每个构建者仅能处理一个特定的架构或者系统。
头交换机
头交换机使用多个消息属性来代替路由键建立路由规则。通过判断消息头的值能否与指定的绑定相匹配来确立路由规则
头交换机可以视为直连交换机的另一种表现形式。头交换机能够像直连交换机一样工作,不同之处在于头交换机的路由规则是建立在头属性值之上,而不是路由键。路由键必须是一个字符串,而头属性值则没有这个约束,它们甚至可以是整数或者哈希值(字典)等
队列
Name
Durable(消息代理重启后,队列依旧存在)
Exclusive(只被一个连接(connection)使用,而且当连接关闭后队列即被删除)
Auto-delete(当最后一个消费者退订后即被删除)
Arguments(一些消息代理用他来完成类似与TTL的某些额外功能
队列名字
队列的名字可以由应用(application)来取,也可以让消息代理(broker)直接生成一个。队列的名字可以是最多255字节的一个utf-8字符串。
若希望AMQP消息代理生成队列名,需要给队列的name参数赋值一个空字符串:
在同一个通道(channel)的后续的方法(method)中,我们可以使用空字符串来表示之前生成的队列名称。
之所以之后的方法可以获取正确的队列名是因为通道可以默默地记住消息代理最后一次生成的队列名称。
以"amq."开始的队列名称被预留做消息代理内部使用。如果试图在队列声明时打破这一规则的话,一个通道级的403 (ACCESS_REFUSED)错误会被抛出
队列持久化
持久化队列(Durable queues)会被存储在磁盘上,当消息代理(broker)重启的时候,它依旧存在,并不是所有的场景和案例都需要将队列持久化
持久化的队列并不会使得路由到它的消息也具有持久性。倘若消息代理挂掉了,重新启动,那么在重启的过程中持久化队列会被重新声明,无论怎样,只有经过持久化的消息才能被重新恢复
如果要指示交换机“E”将消息路由给队列“Q”,那么“Q”就需要与“E”进行绑定。绑定操作需要定义一个可选的路由键(routing key)属性给某些类型的交换机。路由键的意义在于从发送给交换机的众多消息中选择出某些消息,将其路由给绑定的队列
消费者
使用push API,应用(application)需要明确表示出它在某个特定队列里所感兴趣的,想要消费的消息
一个队列可以注册多个消费者,也可以注册一个独享的消费者
每个消费者(订阅者)都有一个叫做消费者标签的标识符。它可以被用来退订消息。消费者标签实际上是一个字符串
消息确认
当消息代理(broker)将消息发送给应用后立即删除。(使用AMQP方法:basic.deliver或basic.get-ok)
待应用(application)发送一个确认回执(acknowledgement)后再删除消息。(使用AMQP方法:basic.ack)
拒绝消息
当一个消费者接收到某条消息后,处理过程有可能成功,有可能失败。应用可以向消息代理表明,本条消息由于“拒绝消息(Rejecting Messages)”的原因处理失败了(或者未能在此时完成)。当拒绝某条消息时,应用可以告诉消息代理如何处理这条消息——销毁它或者重新放入队列。当此队列只有一个消费者时,请确认不要由于拒绝消息并且选择了重新放入队列的行为而引起消息在同一个消费者身上无限循环的情况发生