消息队列有哪些 消息队列( 三 )


优点:命令模式(非topic\queue模式)
XMPP(可扩展消息处理现场协议 , Extensible Messaging and Presence Protocol)是基于可扩展标记语言(XML)的协议 , 多用于即时消息(IM)以及在线现场探测 。适用于服务器之间的准即时操作 。核心是基于XML流传输 , 这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息 , 即使其操作系统和浏览器不同 。
优点:通用公开、兼容性强、可扩展、安全性高 , 但XML编码格式占用带宽大
RabbitMQ 是实现 AMQP(高级消息队列协议)的消息中间件的一种 , 最初起源于金融系统 , 用于在分布式系统中存储转发消息 , 在易用性、扩展性、高可用性等方面表现不俗 。RabbitMQ 主要是为了实现系统之间的双向解耦而实现的 。当生产者大量产生数据时 , 消费者无法快速消费 , 那么需要一个中间层 。保存这个数据 。
RabbitMQ 是一个开源的 AMQP 实现 , 服务器端用Erlang语言编写 , 支持多种客户端 , 如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP 等 , 支持 AJAX 。用于在分布式系统中存储转发消息 , 在易用性、扩展性、高可用性等方面表现不俗 。
Channel(通道)
道是两个管理器之间的一种单向点对点的的通信连接 , 如果需要双向交流 , 可以建立一对通道 。
Exchange(消息交换机)
Exchange类似于数据通信网络中的交换机 , 提供消息路由策略 。
RabbitMq中 , producer不是通过信道直接将消息发送给queue , 而是先发送给Exchange 。一个Exchange可以和多个Queue进行绑定 , producer在传递消息的时候 , 会传递一个ROUTING_KEY , Exchange会根据这个ROUTING_KEY按照特定的路由算法 , 将消息路由给指定的queue 。和Queue一样 , Exchange也可设置为持久化 , 临时或者自动删除 。
Exchange有4种类型:direct(默认) , fanout ,  topic ,  和headers 。
不同类型的Exchange转发消息的策略有所区别:
Binding(绑定)
所谓绑定就是将一个特定的 Exchange 和一个特定的 Queue 绑定起来 。Exchange 和Queue的绑定可以是多对多的关系 。
Routing Key(路由关键字)
exchange根据这个关键字进行消息投递 。
vhost(虚拟主机)
在RabbitMq server上可以创建多个虚拟的message broker , 又叫做virtual hosts (vhosts) 。每一个vhost本质上是一个mini-rabbitmq server , 分别管理各自的exchange , 和bindings 。vhost相当于物理的server , 可以为不同app提供边界隔离 , 使得应用安全的运行在不同的vhost实例上 , 相互之间不会干扰 。producer和consumer连接rabbit server需要指定一个vhost 。
假设P1和C1注册了相同的Broker , Exchange和Queue 。P1发送的消息最终会被C1消费 。
基本的通信流程大概如下所示:
Consumer收到消息时需要显式的向rabbit broker发送basic 。ack消息或者consumer订阅消息时设置auto_ack参数为true 。
在通信过程中 , 队列对ACK的处理有以下几种情况:
即消息的Ackownledge确认机制 , 为了保证消息不丢失 , 消息队列提供了消息Acknowledge机制 , 即ACK机制 , 当Consumer确认消息已经被消费处理 , 发送一个ACK给消息队列 , 此时消息队列便可以删除这个消息了 。如果Consumer宕机/关闭 , 没有发送ACK , 消息队列将认为这个消息没有被处理 , 会将这个消息重新发送给其他的Consumer重新消费处理 。
消息的收发处理支持事务 , 例如:在任务中心场景中 , 一次处理可能涉及多个消息的接收、处理 , 这应该处于同一个事务范围内 , 如果一个消息处理失败 , 事务回滚 , 消息重新回到队列中 。
消息的持久化 , 对于一些关键的核心业务来说是非常重要的 , 启用消息持久化后 , 消息队列宕机重启后 , 消息可以从持久化存储恢复 , 消息不丢失 , 可以继续消费处理 。
fanout 模式
模式特点:
direct 模式
任何发送到Direct Exchange的消息都会被转发到routing_key中指定的Queue 。
如果一个exchange 声明为direct , 并且bind中指定了routing_key , 那么发送消息时需要同时指明该exchange和routing_key 。

秒懂生活扩展阅读