# Kafka 系列 - 消息队列的选择

了解完消息队列的基本信息之后,接下来我们可以考虑消息队列的技术选型问题。

目前使用较多的消息队列有 ActiveMQ、RabbitMQ、ZeroMQ、Kafka、MetaMQ、RocketMQ 等,以及数据库

Redis 也可以实现消息队列的效果。

实际使用中应该使用哪一种呢?解析来我们看一看主流消息队列的特性。

# Redis

Redis 是一个基于 key-value 的内存数据库,一般用缓存场景。但其实 Redis 本身是支持 MQ 功能的,可以作为一个轻量级的队列服务来使用。

网上通过对 RabbitMQ 和 Redis 进行对比试验,对二者的出队和入队操作,个执行 100 万次,每 10 万次记录一次执行时间。测试数据分别为 128Bytes、512Bytes、1k 和 10k 四个大小不同的数据。

结果显示入队时,当数据较小时Redis的性能要高于RabbitMQ,而如果数据大小超过 10k,Redis 则慢得无法忍受;出队时,无论数据大小,Redis 都表现出非常好的性能,而 RabbitMQ 的出队性能则远低于 Redis。

实际应用中,大家一般都不选择 Redis 做消息队列,我想一方面时因为数据的大小对 Redis 的性能会产生较大的影响,另一方面时 Redis 给人的印象是用来做缓存的。因此,Redis 可能更适合做很小规模、业务简单的消息队列场景。

实际上如果我不搜索消息队列的选型,我也不知道 Redis 可以作为消息队列。

# ActiveMQ

ActiveMQ 是 Apache 提供的一个开源的消息系统,完全采用 Java 实现,支持 J2EE 提出的 JMS 规范。

JMS(Java Message Service) 是一组 Java 应用程序接口和响应语法,类似于 Java 数据库的统一访问接口 JDBC,是一种与产商无关的 API,使得 Java 程序能够与不同厂商的消息组件很好地进行通信。

# 特性

  • 服从 JMS 规范
  • 连接灵活:ActiveMQ 提供了广泛的连接协议,支持的协议有:HTTP/S、IP多播、SSL、TCP、UDP等等。
  • 持久化插件和安全插件:ActiveMQ 提供了多种持久化选择以及可以一句用户的需求进行自定义健全和授权。
  • 支持的客户端语言种类多:除了 Java 之外,还有:C/C++,.NET,Perl,PHP,Python,Ruby。
  • 代理集群:支持将多个 ActiveMQ 代理组成一个集群来提供服务。
  • 管理方便:ActiveMQ是以开发者思维被设计的。所以,它并不需要专门的管理员,因为它提供了简单又使用的管理特性。有很多中方法可以监控ActiveMQ不同层面的数据,包括使用在JConsole或者ActiveMQ的WebConsole中使用JMX。通过处理JMX的告警消息,通过使用命令行脚本,甚至可以通过监控各种类型的日志。

# RabbitMQ

Rabbit 是用 Erlang 编写的一个开源的消息队列,本身支持多种协议:AMQP、XMPP、SMTP、STOMP,也正因如此,它非常重量级,更适合于企业级开发。同时实现了 Broker 架构,这意味着在发送给客户端时先在中心队列排队。对路由、负载均衡和数据持久化都有很好的支持。

# 特性

  • 可靠性:提供了多种技术可以让我们在性能和可靠性之间权衡。这些技术包括持久性机制、投递确认、发布者证实和高可用性机制。
  • 灵活的路由:消息在到达队列之前时通过交换机进行路由的。RabbitMQ 为典型的路由逻辑提供多种内置交换机类型。如果你有更复杂的路由需求,可以将这些交换机组合起来使用,你甚至可以实现自己的交换机类型,并且当作 RabbitMQ 的插件来使用。
  • 消息集群:在相同局域网内的多个 RabbitMQ 服务器可以聚合起来作为一个集群来提供服务。
  • 队列高可用:队列可以在集群中的机器上进行镜像,以确保在硬件问题下还保证消息安全。
  • 支持多种消息队列协议。
  • 支持多种语言:用 Erlang 语言编写,支持只要是你能想到的所有编程语言。
  • 管理界面:RabbitMQ 有一个易用的用户界面,使得用户可以监控和管理消息 Broker 的许多方面。
  • 跟踪机制:如果消息异常,RabbitMQ 提供消息跟踪机制,使用者可以找出发生了什么。
  • 插件机制:提供了许多插件,来从多方面进行拓展,也可以编写自己的插件。

# Kafka

Kafka 是 Apache 下的一个子项目,是一个高性能跨语言分布式发布/订阅消息队列系统。

# 特性

  • 快速持久化:可以在 O(1) 的系统开销下进行消息持久化。
  • 高吞吐:在一台普通的服务器上既可以达到 10 W/s 的吞吐率
  • 完全的分布式系统,Broker、Producer、Consumer 都原生地支持分布式,自动实现负载均衡。
  • 无需停机即可拓展机器。
  • 丰富地消息拉取模型、高效订阅者水平拓展、实时地消息订阅、亿级地消息堆积能力、定时删除机制。

# RocketMQ

RocketMQ 出自阿里的开源产品,用 Java 语言实现,在设计时参考了 Kafka,并做了一些自己的改进,消息可靠性上比 Kafka 更好。RocketMQ 在阿里内部广泛应用在订单、交易、充值、流计算、消息推送、日志流式处理、binglog 分发场景等。

# 特性

  • 基于队列模型:具有高性能、高可靠、高实时、分布式等特点
  • Producer、Consumer、队列都支持分布式。
  • 能够保证严格的消息顺序
  • 提供丰富的消息拉取模式
  • 高效的订阅者水平拓展能力
  • 实时的消息订阅机制
  • 亿级消息堆积能力
  • 较少的外部依赖

消息队列对比

从上面的表格对可以得出几个简单结论:

  • 无论是在单机吞吐量还是可用性方面,ActiveMQ 和 RabbitMQ 都差不多,而 RocketMQ 和 Kafka 差不多
  • 在功能特性方面,ActiveMQ、RabbitMQ、RocketMQ 功能都比较完善,Kafka 功能性较弱。

# 归纳

# Redis

缓存才是主业,队列功能只是附加功能,更适合用于业务简单、规模小地业务场景。

# ActiveMQ、RabbitMQ

ActiveMQ 和 RabbitMQ 功能丰富但是单机性能和可用性稍弱。

对于中小型公司,因为其本身的研发投入比较少、性能要求不会太高,所以可以选择 ActiveMQ 或者 RabbitMQ。

两者中,RabbitMQ 的更新频率更快和社区更加活跃,所以可以优先选择 RabbitMQ。

# Kafka、RocketMQ

Kafka、RocketMQ 的单机吞吐量、可用性都比较高,但是所使用的技术更加复杂,对研发人员的要求也高。

对于大型互联网公司,其对于吞吐量和可用性都有较高的要求,并且有定制化的需求,所以大型公司可以选择 Kafka 和 RocketMQ。

两者中,RocketMQ 牺牲了一些性能,换来业务特性的支持。而 Kafka 则支持机制的吞吐量。所以在业务场景下使用 RocketMQ,而在非业务场景使用 Kafka。

框架 特点 业务场景
Redis 功能简单 简单的业务场景、规模小
RabbitMQ、ActiveMQ 功能丰富、吞吐量和可用性适中 稍微复杂的业务场景、规模适中
RocketMQ 功能丰富、定制化强、吞吐量和可用性高 复杂的业务场景、规模大
Kafka 吞吐量、可用性超高 规模超大的非业务场景

# 参考

上次更新: 2023/10/15