### RabbitMQ

RabbitMQ作为消息中间件的一种实现,常常被当作一种服务总线来使用。
RabbitMQ原生就支持消息队列和发布订阅的两种消息模式。
其他一些流行的消息中间件的实现有ActiveMQ,ZeroMQ,Azure Service Bus以及Amazon Simple Queue Service(SQS)。
这些消息中间件的实现有许多共通的地方,许多概念大部分都适用于这些中间件。

1、队列。
RabbitMQ支持典型的开箱即用的消息队列。
开发者可以定义一个命名队列,然后发布者可以向这个命名队列中发送消息。最后消费者可以通过这个命名队列获取待处理的消息。

2、消息交换器。
RabbitMQ使用消息交换器来实现发布/订阅模式。
发布者可以把消息发布到消息交换器上而不用知道这些消息都有哪些订阅者。
每一个订阅了交换器的消费者都会创建一个队列;
然后消息交换器会把生产的消息放入队列以供消费者消费。
消息交换器也可以基于各种路由规则为一些订阅者过滤消息。

### Apache Kafka

Apache Kafka不是消息中间件的一种实现。相反它只是一种分布式流式系统。
不同于基于队列和交换器的RabbitMQ,Kafka的存储层是使用分区事务日志来实现的。
Kafka也提供流式API用于实时的流处理以及连接器API用来更容易的和各种数据源集成。

1、主题
Kafka没有实现队列这种东西。相应的,Kafka按照类别存储记录集,并且把这种类别称为主题topic,就是个唯一标志。
Kafka为每个主题维护一个消息分区日志。每个分区都是由有序的不可变的记录序列组成,并且消息都是连续的被追加在尾部。
当消息到达时,Kafka就会把他们追加到分区尾部。
默认情况下,Kafka使用轮询分区器(partitioner)把消息一致的分配到多个分区上。
Kafka可以改变创建消息逻辑流的行为。
例如,在一个多租户的应用中,我们可以根据每个消息中的租户ID创建消息流。
IoT场景中,我们可以在常数级别下根据生产者的身份信息(identity)将其映射到一个具体的分区上。
确保来自相同逻辑流上的消息映射到相同分区上,这就保证了消息能够按照顺序提供给消费者。

2、Kafka实现的消息模式
Kafka的实现很好实现了发布/订阅模式。

生产者可以向一个具体的主题发送消息,然后多个消费者组可以消费相同的消息。
每一个消费者组都可以独立的伸缩去处理相应的负载。
我们可以创建一个主题,这个主题和拥有一个消费者的消费组进行关联,这样我们就模拟出了一个典型的消息队列。
Kafka是按照预先配置好的时间保留分区中的消息,而不是根据消费者是否消费了这些消息。这种保留机制可以让消费者自由的重读之前的消息。
开发者也可以利用Kafka的存储层来实现诸如事件溯源和日志审计功能。

### RabbitMQ和Kafka的显著差异

1. Kafka最适用于数据的流式处理,但是RabbitMQ对流式中的消息就很难保持它们的顺序, 所以如果需要顺序, kafka更加合适。
2. RabbitMQ内置重试逻辑和死信(dead-letter)交换器,但是Kafka只是把这些实现逻辑交给用户来处理,所以消息路由和过滤方面,RabbitMQ更好一些 。

### 优先选择RabbitMQ的条件:

高级灵活的路由规则;
消息时序控制(控制消息过期或者消息延迟);
高级的容错处理能力,在消费者更有可能处理消息不成功的情景中(瞬时或者持久);
更简单的消费者实现。

### 优先选择Kafka的条件:

严格的消息顺序;
延长消息留存时间,包括过去消息重放的可能;
传统解决方案无法满足的高伸缩能力。
大部分情况下这两个消息平台都可以满足我们的要求。

### 思考的限制和决定

当前开发者对这两个消息平台的了解;
托管云解决方案的可用性(如果适用);
每种解决方案的运营成本;
适用于我们目标栈的SDK的可用性。
当开发复杂的软件系统时,我们可能被诱导使用同一个消息平台去实现所有必须的消息用例。
但是,通常同时使用这两个消息平台能够带来更多的好处。

例如,在一个事件驱动的架构系统中,我们可以使用RabbitMQ在服务之间发送命令,并且使用Kafka实现业务事件通知。
原因是事件通知常常用于事件溯源,批量操作(ETL风格),或者审计目的,因此Kafka的消息留存能力就显得很有价值。
相反,命令一般需要在消费者端做额外处理,并且处理可以失败,所以需要高级的容错处理能力。

 

版权声明:本文为adamans原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/adamans/articles/13434347.html