「极速聊科技」RabbitMQ 还是 Kafka?,讲真,应该选择


作为一个有丰富经验的微服务系统架构师 , 经常有人问我 , 应该选择RabbitMQ还是Kafka? 。
「极速聊科技」RabbitMQ 还是 Kafka?,讲真,应该选择
文章图片
基于某些原因 , 许多开发者会把这两种技术当做等价的来看待 。 的确 , 在一些案例场景下选择RabbitMQ还是Kafka没什么差别 , 但是这两种技术在底层实现方面是有许多差异的 。
不同的场景需要不同的解决方案 , 选错一个方案能够严重的影响你对软件的设计 , 开发和维护的能力 。
这篇文章会先介绍一下基本的异步消息模式 , 然后再介绍一下RabbitMQ和Kafka以及他们的内部结构信息 。 第二部分主要介绍这两种技术的主要不同点以及他们各自的优缺点 , 最后我们会说明一下怎样选择这两种技术 。
异步消息模式
【「极速聊科技」RabbitMQ 还是 Kafka?,讲真,应该选择】消息队列
利用消息队列可以解耦生产者和消费者 。 多个生产者可以向同一个消息队列发送消息 。
但是 , 一个消息在被一个消息者处理的时候 , 这个消息在队列上会被锁住或者被移除并且其他消费者无法处理该消息 。 也就是说一个具体的消息只能由一个消费者消费 。
消息队列
需要额外注意的是 , 如果消费者处理一个消息失败了 , 消息系统一般会把这个消息放回队列 , 这样其他消费者可以继续处理 。
消息队列除了提供解耦功能之外 , 它还能够对生产者和消费者进行独立的伸缩 , 以及提供对错误处理的容错能力 。
发布/订阅模式中 , 单个消息可以被多个订阅者并发的获取和处理 。
RabbitMQ
RabbitMQ作为消息中间件的一种实现 , 常常被当作一种服务总线来使用 。 RabbitMQ原生就支持上面提到的两种消息模式 。
其他一些流行的消息中间件的实现有ActiveMQ , ZeroMQ , AzureServiceBus以及AmazonSimpleQueueService 。
这些消息中间件的实现有许多共通的地方;这边文章中提到的许多概念大部分都适用于这些中间件 。
队列
RabbitMQ支持典型的开箱即用的消息队列 。 开发者可以定义一个命名队列 , 然后发布者可以向这个命名队列中发送消息 。 最后消费者可以通过这个命名队列获取待处理的消息 。
消息交换器
RabbitMQ使用消息交换器来实现发布/订阅模式 。 发布者可以把消息发布到消息交换器上而不用知道这些消息都有哪些订阅者 。
RabbitMQ消息交换器
需要重点注意的是RabbitMQ支持临时和持久两种订阅类型 。 消费者可以调用RabbitMQ的API来选择他们想要的订阅类型 。
根据RabbitMQ的架构设计 , 我们也可以创建一种混合方法——订阅者以组队的方式然后在组内以竞争关系作为消费者去处理某个具体队列上的消息 , 这种由订阅者构成的组我们称为消费者组 。
发布/订阅与队列的联合使用
ApacheKafka
ApacheKafka不是消息中间件的一种实现 。 相反 , 它只是一种分布式流式系统 。
不同于基于队列和交换器的RabbitMQ , Kafka的存储层是使用分区事务日志来实现的 。
Kafka也提供流式API用于实时的流处理以及连接器API用来更容易的和各种数据源集成;当然 , 这些已经超出了本篇文章的讨论范围 。
云厂商为Kafka存储层提供了可选的方案 , 比如AzureEventHubsy以及AWSKinesisDataStreams等 。
对于Kafka流式处理能力 , 还有一些特定的云方案和开源方案 , 不过 , 话说回来 , 它们也超出了本篇的范围 。
主题
Kafka没有实现队列这种东西 。 相应的 , Kafka按照类别存储记录集 , 并且把这种类别称为主题 。
Kafka为每个主题维护一个消息分区日志 。 每个分区都是由有序的不可变的记录序列组成 , 并且消息都是连续的被追加在尾部 。
当消息到达时 , Kafka就会把他们追加到分区尾部 。 默认情况下 , Kafka使用轮询分区器把消息一致的分配到多个分区上 。


推荐阅读