# 一、消息中间件选型

常用的 MQ组件有 KafkaRabbitMQRocketMQActiveMQ、ZeroMQ、MetaMQ。当然 Kafka的功能更加强大,其它 MQ都有自己的特点和优势,如下:

特性 Kafka RabbitMQ RocketMQ ActiveMQ
开发语言 Scala Erlang Java Java
单击吞吐量 十万级 万级 十万级 万级
时效性 ms级以内 us(微秒)级 ms级 ms级
可用性 非常高(分布式架构) 高(主从架构) 非常高(分布式架构) 高(主从架构)
功能特性 只支持主要的 MQ功能,像一些消息查询,消息回溯等功能没有提供,毕竟是为大数据提供的,大数据领域应用广。 并发能力很强,性能及其好,延迟极低,管理界面丰富 MQ功能比较完备,扩展性强 成熟的产品,在很多公司得到应用,有很多成熟的文档,支持各种协议

# 一、中间件类型

# Kafka

Kafka 是 LinkedIn开源的分布式发布-订阅消息系统,目前归属于 Apache顶级项目。Kafka主要特点是基于 Pull的模式来处理消息,消息有序,通过控制能够保证所有消息被消费且仅被消费一次,追求高吞吐量,一开始的目的就是用于日志收集和传输。支持复制、事务,对消息的重复、丢失、错误没有严格要求,适合产生大量数据的互联网服务的数据收集业务。完全的分布式系统,Broker、Producer、Consumer都原生自动支持分布式,自动实现负载均衡。

号称大数据的杀手锏,谈到大数据领域内的消息传输,则绕不开Kafka,这款为大数据而生的消息中间件,以其百万级TPS(单机写入TPS约在百万条/秒)的吞吐量名声大噪,迅速成为大数据领域的宠儿,在数据采集、传输、存储的过程中发挥着举足轻重的作用。可用性非常高,kafka是分布式的,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用。有优秀的第三方 Kafka Web管理界面 Kafka-Manager

缺点:① Kafka单机超过 64个队列/分区,Load会发生明显的飙高现象,队列越多,load越高,发送消息响应时间变长。 使用短轮询方式,实时性取决于轮询间隔时间。 消费失败不支持重试。 支持消息顺序,但是一台代理宕机后,就会产生消息乱序。

# RabbitMQ

RabbitMQ是使用 Erlang语言开发的开源消息队列系统,支持很多的协议 AMQP,XMPP,SMTP,STOMP协议。AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。AMQP协议使的它变的非常重量级,更适合于企业级的开发,对路由(Routing),负载均衡(Load balance)、数据一致性、稳定性可靠性要求很高的场景,对性能和吞吐量的要求还在其次。健壮、稳定、易用、跨平台、支持多种语言、文档齐全。开源提供的管理界面非常棒,用起来很好用。社区活跃度高。

缺点:① Erlang开发,很难去看懂源码,基本职能依赖于开源社区的快速维护和修复bug,不利于做二次开发和维护。 RabbitMQ确实吞吐量会低一些,这是因为他做的实现机制比较重。 需要学习比较复杂的接口和协议,学习和维护成本较高。

# RocketMQ

RocketMQ是阿里开源的消息中间件,它是纯 Java开发,具有高吞吐量、高可用性、适合大规模分布式系统应用的特点。RocketMQ思路起源于 Kafka,并做出了自己的一些改进,它对消息的可靠传输事务性做了优化,目前在阿里集团被广泛应用于交易、充值、流计算、消息推送、日志流式处理、binglog分发等场景。消息可靠性非常高,经过参数优化配置,消息可以做到0丢失。MQ功能较为完善,还是分布式的,扩展性好。支持10亿级别的消息堆积,不会因为堆积导致性能下降。源码是 Java,我们可以自己阅读源码,定制自己公司的MQ,可以掌控。

天生为金融互联网领域而生,对于可靠性要求很高的场景,尤其是电商里面的订单扣款,以及业务削峰,在大量交易涌入时,后端可能无法及时处理的情况。RoketMQ在稳定性上可能更值得信赖,这些业务场景在阿里双11已经经历了多次考验,如果你的业务有上述并发场景,建议可以选择RocketMQ。

缺点:① 支持的客户端语言不多,目前是 java及c++,其中 c++不成熟。 社区活跃度一般。 没有在 MQ核心中去实现 JMS等接口,有些系统要迁移需要修改大量代码。

# ActiveMQ

Apache ActiveMQ速度快,支持许多跨语言客户端和协议,带有易于使用的企业集成模式和许多高级功能,同时完全支持JMS 1.1和J2EE 1.4。Apache ActiveMQ是在 Apache 2.0许可下发布。有较低的概率丢失数据。

缺点: 官方社区现在对 ActiveMQ 5.x维护越来越少,较少在大规模吞吐的场景中使用。

# 三、压力测试

对比 Kafka、RabbitMQ、RocketMQ发送消息的性能。压测我只关注服务端的性能指标,所以压测的标准是不断增加发送端的压力,直到系统吞吐量不再上升,而响应时间拉长。这时服务端已出现性能瓶颈,可以获得相应的系统最佳吞吐量。在同步发送场景中,三个消息中间件的表现区分明显:

# Kafka

Kafka 的吞吐量高达17.3w/s,是高吞吐量消息中间件的行业老大。这主要取决于它的队列模式保证了写磁盘的过程是线性IO。此时 Broker磁盘IO已达瓶颈。

# RocketMQ

RocketMQ也表现不俗,吞吐量在 11.6w/s,磁盘IO已接近100%。RocketMQ的消息写入内存后即返回ack,由单独的线程专门做刷盘的操作,所有的消息均是顺序写文件。

# RabbitMQ

RabbitMQ的吞吐量5.95w/s,CPU资源消耗较高。它支持 AMQP协议,实现非常重量级,为了保证消息的可靠性在吞吐量上做了取舍。我们还做了 RabbitMQ在消息持久化场景下的性能测试,吞吐量在 2.6w/s左右。

测试结论: 同步发送的性能上 Kafka>RocketMQ>RabbitMQ

中间件

# 四、在架构模型方面

# Kafka

Kafka遵从一般的 MQ结构,Producer,Broker,Consumer,以 Consumer为中心,消息的消费信息保存的客户端 Consumer上,Consumer根据消费的点,从 Broker上批量 pull数据,无消息确认机制。

# RabbitMQ

RabbitMQ遵循 AMQP协议,RabbitMQ的 Broker由 Exchange,Binding,Queue组成,其中 Exchange和 Binding组成了消息的路由键。客户端 Producer通过连接 Channel和 Server进行通信,Consumer从 Queue获取消息进行消费(长连接,Queue有消息会推送到 Consumer端,Consumer循环从输入流读取数据)。RabbitMQ以 Broker为中心,有消息的确认机制。

# 五、吞吐量

# Kafka

Kafka具有高的吞吐量,内部采用消息的批量处理,zero-copy机制,数据的存储和获取是本地磁盘顺序批量操作,具有 O(1)的复杂度,消息处理的效率很高。

# RabbitMQ

RabbitMQ在吞吐量方面稍逊于 Kafka,他们的出发点不一样,RabbitMQ支持对消息的可靠的传递,支持事务,不支持批量的操作。基于可靠存储的要求,存储可以采用内存或者硬盘。

# 六、集群负载均衡方面

# Kafka

Kafka 采用 Zookeeper对集群中的 Broker、Consumer进行管理,可以注册 Topic到 Zookeeper上。通过 Zookeeper的协调机制,Producer保存对应 Topic的 Broker信息,可以随机或者轮询发送到 Broker上。并且 Producer可以基于语义指定分片,消息发送到 Broker的某分片上。

# RabbitMQ

RabbitMQ 的负载均衡需要单独的 loadbalancer进行支持。

# 七、总结

Rabbitmq 比 Kafka可靠,Kafka更适合 IO高吞吐的处理,比如 ELK日志收集

Kafka 和 RabbitMq都是以分布式部署为目的。但是他们对消息语义模型的定义的假设是非常不同的。我对"AMQP 更成熟"这个论点是持怀疑态度的。让我们用事实说话来看看用什么解决方案来解决你的问题。
【1】以下场景比较适合使用 Kafka。你有大量的事件(10万以上/秒)、你需要以分区的,顺序的,至少传递成功一次到混杂了在线和打包消费的消费者、你希望能重读消息、你能接受目前是有限的节点级别高可用或者说你并不介意通过论坛/IRC工具得到还在幼儿阶段的软件的支持。
【2】以下场景你比较适合使用 RabbitMQ。你有较少的事件(2万以上/秒)并且需要通过复杂的路由逻辑去找到消费者、你希望消息传递是可靠的、你并不关心消息传递的顺序、你需要现在就支持集群-节点级别的高可用或则说你需要7*24小时的付费支持(当然也可以通过论坛/IRC工具)。

(adsbygoogle = window.adsbygoogle || []).push({});