看到一篇非常好的对比 Kafka 和 RabbitMQ 的文章,简化一下写在这里。原文参考底部。
功能
优先级队列
优先级队列不同于先进先出队列,优先级高的消息具备优先被消费的特权。这个优先级队列有一个前提:如果消费的速度大于生产的速度,消息无法堆积并排序,那么就不能保证优先级了。
延迟队列
延迟队列一个典型应用是用户下单后没有支付,一定时间后自动取消订单。延迟列队一般分两种:基于消息的延迟和基于队列的延迟。基于消息的延迟是利用优先级队列,插入后重新排序,延迟低的拍前面,每次都排序肯定会对性能造成很大的影响。实际应用中大多采用基于队列的延迟,设置不同延迟级别的队列,比如5s、10s、30s等,每个队列中消息的延迟时间都是相同的。
死信队列
由于某些原因消息无法被正确的投递,为了确保消息不会被无故的丢弃,一般将其置于一个特殊角色的队列,这个队列一般称之为死信队列。与此对应的还有一个“回退队列”的概念,试想如果一个消息被消费多次都失败了,系统决定不再重试,就将其放入一个回退队列。
重试队列
重试队列结合了延迟队列和回退队列。当消费失败,系统将其放入20s的延迟队列,如果再次失败,则放入20s的队列。
消费模式
消费模式分为推(push)模式和拉(pull)模式。推模式是指由队列主动推送,实时性较好,不过要确保不会压垮消费端。而拉模式实时性较推模式差,但是可以根据自身的处理能力而控制拉取的消息量。
广播消费
广播模式即发布/订阅(Pub/Sub)模式。队列通过推模式,将消息推送给所有订阅者。
消息回溯
相当于日志。消息回溯可以用于 debug 外,还有索引恢复、本地缓存重建,有些业务补偿方案也可以采用回溯的方式来实现。
消息堆积+持久化
流量削峰是消息中间件的一个非常重要的功能,而这个功能其实得益于其消息堆积能力。从某种意义上来讲,如果一个消息中间件不具备消息堆积的能力,那么就不能把它看做是一个合格的消息中间件。特别一提的是,由于 Kafka 是基于硬盘的,所以整个消息队列可以当成数据库来用。
消息追踪
对于消息追踪最通俗的理解就是要知道消息从哪来,存在哪里以及发往哪里去。基于此功能下,我们可以对发送或者消费完的消息进行链路追踪服务,进而可以进行问题的快速定位与排查。
消息过滤
消息过滤是指按照既定的过滤规则为下游用户提供指定类别的消息。比如 Kafka 的 topic。
多租户
各个用户看不到彼此的队列。
多协议
一般消息队列支持的协议有 AMQP、MQTT、STOMP、XMPP等
跨语言支持
提供各种语言的客户端
流量控制
流量控制(flow control)针对的是发送方和接收方速度不匹配的问题,提供一种速度匹配服务抑制发送速率使接收方应用程序的读取速率与之相适应。通常的流控方法有Stop-and-wait、滑动窗口以及令牌桶等。
消息顺序性
必须保证消息严格有序
安全机制
是否提供 TLS/SSL,密码登录等机制
消息幂等性
对于确保消息在生产者和消费者之间进行传输而言一般有三种传输保障(delivery guarantee):At most once,至多一次,消息可能丢失,但绝不会重复传输;At least once,至少一次,消息绝不会丢,但是可能会重复;Exactly once,精确一次,每条消息肯定会被传输一次且仅一次。对于大多数消息中间件而言,一般只提供At most once和At least once两种传输保障,对于第三种一般很难做到,由此消息幂等性也很难保证。
Kafka自0.11版本开始引入了幂等性和事务,Kafka的幂等性是指单个生产者对于单分区单会话的幂等,而事务可以保证原子性地写入到多个分区,即写入到多个分区的消息要么全部成功,要么全部回滚,这两个功能加起来可以让Kafka具备EOS(Exactly Once Semantic)的能力。
事务性消息
即事务开始(Begin Transaction)和事务结束(End Transaction)之间执行的全体操作要么都成果,要么都失败。
功能项 | Kafka(1.1.0) | RabbitMQ(3.6.10) |
---|---|---|
优先级队列 | 不支持 | 支持 |
延迟队列 | 不支持 | 支持 |
死信队列 | 不支持 | 支持 |
重试队列 | 不支持 | 不支持 |
消费模式 | 拉取 | 推+拉 |
广播消费 | 支持 | 支持 |
消息回溯 | 支持(offset和timestamp两种维度) | 不支持 |
消息堆积 | 支持 | 支持(性能不如Kafka) |
持久化 | 支持 | 支持 |
消息追踪 | 不支持 | 支持(Firehose) |
消息过滤 | 客户端级别支持 | 不支持 |
多租户 | 支持 | 支持 |
多协议 | 不支持 | 支持 |
跨语言 | 支持 | 支持 |
流量控制 | client和user级别 | 支持 |
消息顺序性 | 单分区级别 | 不严格 |
安全机制 | (TLS/SSL、SASL)身份认证和(读写)权限控制 | 与Kafka相似 |
幂等性 | 支持单个生产者单分区单会话的幂等性 | 不支持 |
事务性消息 | 支持 | 支持 |
选型的建议
消息中间件选型切忌一味的追求性能或者功能,性能可以优化,功能可以二次开发。如果要在功能和性能方面做一个抉择的话,那么首选性能,因为总体上来说性能优化的空间没有功能扩展的空间大。然而对于长期发展而言,生态又比性能以及功能都要重要。
参考:https://blog.csdn.net/u013256816/article/details/79838428