============================

RabbitMQ 术语

============================

RabbitMQ 有很多术语和Kafka不一样, 理解这些术语十分重要.

1. Broker: 一个RabbitMQ实例就是一个 Broker.

2. VHost(Virtual Host): 一个RabbitMQ实例可包含多个VHost, 每个VHost都有自己的身份验证机制. 在一个VHost中包含多个exchange和队列和binding. 每个RabbitMQ服务器都有一个默认的vhost 是 "/".

3. Exchange, 不要翻译为信箱, 它不具有存储功能, 应该翻译为交换机, 它就是一个路由规则表. 消息是经过 exchange 处理转到 queue 中的, 它本身不存储消息.

4. Binding, 绑定, 可以理解为一个路由规则, 通过Binding的桥接, Exchange和Queue之间形成了一个多对多的关系.

5. Queue, 消息队列, 用来保存消息直到发送给消费者, 它是消息的容器, 也是消息的终点, 一个消息可以投递到一个或多个队列.

6. Connection, 网络连接, 比如一个TCP连接

7. Channel, 信道, 它是一个建立在TCP connection之上多路复用的虚拟连接, 因为建立和销毁一个TCP连接的代价都很高, 所以引入了Channel概念, 以复用一个TCP连接. 所有的命令和消息都是通过信道传递的.

Exchange类型:

1. direct : [默认类型]如果消息中的路由键(routing key)和Binding规则的 binding key完全一致, 则消息会被转到名为routing key的队列中.

2. fanhout: 对于 fanout 类型的exchange, 它可以直接绑定多个队列, 如果一个消息发到了 fanhout 类型的exchange, 则该消息会被广播到它下面的所有队列中.

3. topic: 这是比direct更灵活的一种路由规则, 它是按照模式匹配来做路由, 消息的路由键和binding的key键都使用点号分隔, 比如写成 usa.news.student样子, binding的key键可以使用通配符#号和*号, *号匹配一个单词, #号匹配0个或多个单词. 比如: 消息routing key为 usa.news.student, 能和 usa.# 的binding匹配, 但不能和usa.* 的binding匹配.

4. headers, 匹配消息的header, 而不是路由键, 性能较差, 完全可以使用 direct 类型代替.

============================

RabbitMQ 和 Kafka 的对比:

============================

1. 队列的数据分布和吞吐能力对比:

RabbitMQ 队列容量不能超过单机存储.

RabbitMQ 队列的最大的吞吐能力不会超过单机的网络吞吐能力.

RabbitMQ 集群可以包含多个节点, 每个节点都有一个 broker 负责本机上的管理工作, 并且broker之间可以相互通信. 一个队列可在多个broker上分布, 但仅在一个broker上是 master queue, 其他broker 都是mirror, 注意是mirror. 不管是消息生产者还是消息消费者, 都是从master queue中读写的, mirror 队列不承担负载平衡, 仅仅是起到消息备份作用, 所以 rabbitmq 队列容量不能超过单机存储, 每个队列的最大的吞吐能力不会超过单机的网络吞吐能力.

2. 消费模式

RabbitMQ 支持 由Broker 主动 push 消息到消费端, 可以由消费端主动pull 消费.

kafka 仅仅支持消费端的pull模式.

3. 消息回溯

使用 MQ 做接口, 经常有人会说"消息丢失", Kafka 验证这个问题方法很简单, 换个consumer group 就可以从新消费 topic 中的消息.

但RabbitMQ中的消息, 一旦被消费了就会被标记删除, 没法儿回溯. 有一个不完美的的解决方法, 我们的消息经由 topic exchange 存储到两个队列中, 一个作为主要消费队列, 另一个队列专门用于验证(队列设置TTL).

4. 消息的顺序性

Kafka: 只有单 partition 的 topic 能保证时序性

RabbitMQ: 将消息使用同步的方式打到一个queue中, 并采用一个消费者去消费, 能保证顺序.

5. 使用场景

吞吐量超过单机处理能力, 只能选 Kafka, 队列容量超过单机存储, 只能选 Kafka.

对可靠性非常关注, 最好选 RabbitMQ.

其他场景理论上两者都适合, 需要认真评估选型.


============================

参考

============================

如何保证消息队列的高可用和幂等性以及数据丢失,顺序一致性

​https://www.jianshu.com/p/7a6deaba34d2​

再谈消息队列技术

https://www.jianshu.com/p/69bf7d8beec5

开源软件成熟度评测报告-分布式消息中间件

消息队列之 RabbitMQ

https://www.jianshu.com/p/79ca08116d57

springboot(八):RabbitMQ详解

RabbitMQ和Kafka到底怎么选?

(译)RabbitMQ VS Apache Kafka (四)—— 应用场景如何选择?