Skip to content

消息队列介绍 🚀

1、什么是MQ ? 🚀

MQ ( MessageQueue ),消息队列。 队列,是一种先进先出( FIFO )的数据结构。消息由生产者发送到MQ进行排队,然后按原来的顺序交由消息的消费者进行处理,QQ和微信就是典型的MQ。

MQ的作用主要有以下三个方面:

异步 🚀

作用:异步能减少系统不必要的等待,提高响应速度、吞吐量

例子:快递员发快递,直接到客户家效率会很低。引入菜鸟驿站后,快递员只需要把快递放到菜鸟驿站,就可以继续发其他快递去了。客户再按自己的时间安排去菜鸟驿站取快递。

解耦 🚀

例子:《 Thinking in JAVA 》很经典,但是都是英文,我们看不懂,所以需要编辑社,将文章翻译成其他语言,这样就可以完成英语与其他语言的交流。

作用:

1、服务之间进行解耦,才可以减少服务之间的影响。提高系统整体的稳定性、可扩展性。

2、解耦后可以实现数据分发。生产者发送一个消息后,可以由一个或者多个消费者进行消费,并且消费者的增加或者减少对生产者没有影响。

削峰填谷 🚀

例子:长江每年都会涨水,但是下游出水口的速度是基本稳定的,所以会涨水。引入三峡大坝后,可以把水储存起来,下游慢慢排水。

作用:以稳定的系统资源应对突发的流量冲击

2、MQ缺点 🚀

系统可用性降低 🚀

系统引入的外部依赖增多,系统的稳定性就会变差。一旦MQ宕机,对业务会产生影响。这就需要考虑如何保证MQ的高可用。

系统复杂度提高 🚀

引入MQ后系统的复杂度会大大提高。以前服务之间可以进行同步的服务调用,引入MQ后,会变为异步调用,数据的链路就会变得更复杂。

并且还会带来其他一些问题,比如:

  • 如何保证消息不会丢失?
  • 如何保证消息不被重复消费?
  • 如何保证消息消费顺序?

一致性问题 🚀

A 系统处理完业务,通过 MQ 发送消息给 B系统、C系统,进行后续的业务处理。如果B系统处理成功,C系统处理失败,这种情况怎么办?这就需要考虑如何保证消息数据处理的一致性。

3、流行的MQ产品特点比较 🚀

流行的MQ产品包括Kafka、RabbitMQ、RocketMQ,我们对这三个产品做下简单的比较,重点需要理解他们的适用场景

优点缺点使用场景
kafka吞吐量非常大,性能非常好,集群高可用会丢数据,功能比较单一日志分析,大数据采集
RabbitMQ消息可靠性高,功能全面吞吐量比较低,消息积累会影响性能,erlang语言不好定制小规模场景
RocketMQ高吞吐,高性能,高可用,功能全面开源版功能不如云上版,官方文档比较简单,客户端只支持java几乎全场景

Kafka 🚀

Kafka 是 LinkedIn 开源的分布式 发布/订阅 消息系统, 目前归属于 Apache 顶级项目。 Kafka 主要特点是基于 Pull 的模式来处理消息消费, 追求高吞吐量, 一开始的目的就是用于日志收集和传输。 0.8版本开始支持复制, 不支持事务, 对消息的重复、 丢失、 错误没有严格要求, 适合产生大量数据的互联网服务的数据收集业务

RabbitMQ 🚀

RabbitMQ 是使用 Erlang 语言开发的开源消息队列系统, 基于 AMQP 协议来实现。 AMQP 的主要特征是面向消息、 队列、 路由(包括点对点和发布/订阅) 、 可靠性、 安全。 AMQP 协议更多用在企业系统内, 对数据一致性、 稳定性和可靠性要求很高的场景, 对性能和吞吐量的要求还在其次

RocketMQ 🚀

早期淘宝内部的交易系统,使用了淘宝自主研发的 Notify 消息中间件。基于 MySQL 作为消息存储媒介, 可完全水平扩容。为了进一步降低成本, 我们认为存储部分可以进一步优化。

2011年初,Linkin 开源了 Kafka 这个优秀的消息中间件, 淘宝中间件团队在对 Kafka 做过充分 Review 之后, Kafka 无限消息堆积, 高效的持久化速度吸引了我们, 但是同时发现这个消息系统主要定位于日志传输, 对于使用在淘宝交易、 订单、 充值等场景下还有诸多特性不满足。

为此我们重新用 Java 语言编写了 RocketMQ,定位于非日志的可靠消息传输(日志场景也 OK) , 目前 RocketMQ 在阿里集团被广泛应用在订单、交易、充值、流计算、消息推送、日志流式处理、binglog 分发等场景

有关测试结论 🚀

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

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

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

在服务端处理同步发送的性能上, Kafka > RocketMQ > RabbitMQ

对比了最简单的小消息发送场景,Kafka 暂时胜出。 但是,作为经受过历次双十一洗礼的 RocketMQ,在互联网应用场景中更有它优越的一面

对比 🚀

功能消息队列 RocketMQApache RocketMQ(开源)Apache KafkaRabbitMQ
安全防护支持不支持不支持支持
主子账号支持支持不支持不支持不支持
可靠性- 同步刷盘 - 同步双写 - 超 3 份数据副本 - 99.99999999%- 同步刷盘 - 异步刷盘异步刷盘, 丢数据概率高同步刷盘
可用性- 非常好, 99.95% - Always Writable
横向扩展能力- 支持平滑扩展 - 支持百万级 QPS支持支持- 集群扩容依赖前端 - LVS 负载均衡调度
Low Latency支持不支持不支持不支持
消费模型Push / PullPush / PullPullPush / Pull
定时消息支持(可精确到秒级)支持(只支持 18 个固定 Level)不支持支持
事务消息支持不支持不支持不支持
顺序消息支持支持支持不支持
全链路消息轨迹支持不支持不支持不支持
消息堆积能力百亿级别 不影响性能百亿级别 影响性能影响性能影响性能
消息堆积查询支持支持不支持不支持
消息回溯支持支持不支持不支持
消息重试支持支持不支持支持
死信队列支持支持不支持支持
性能(常规)非常好 百万级 QPS非常好 十万级 QPS非常好 百万级 QPS一般 万级 QPS
性能(万级 Topic 场 景)非常好 百万级 QPS非常好 十万级 QPS
KafkaRocketMqRabbitMQRabbitMQ
关注度
成熟度成熟比较成熟成熟
所属社区/公司ApacheAlibaba ApacheMozilla Public License
社区活跃度
文档
特点吞吐量与消息积累都很强大 Topic 太多会影响性能。各个环节分布式扩展设 计, 主从 HA; 支持上万 个队列; 多种消费模式; 性能很好由于 Erlang 语言的并发能力, 性能很好
授权方式开源开源开源
开发语言scalaJavaErlang
支持的协议一套自行设计的基于 TCP 的二 进制协议自己定义的一 套(社区提供 JMS--不成熟)AMQP
客户端支持语言C/C++,Python,Go,Erlang,Java 等Java C++( 不成熟)Java、 C、 C++、 Python、 PHP、 Perl、 .net 等
持久化磁盘文件磁盘文件内存、 文件
事务不支持支持不支持
性能( 海量消息堆积 场景)非常好 百万级 QPS非常好 十万级 QPS
集群ZookeeperNameserverRabbitMQ
单机支持的队列单机超过 64 个队列, 性能会明显 下降单机最高支持 5W 个队列, 性能没有明显变化依赖于内存
定时消息不支持开源版仅支持定时 Level不支持
顺序消费支持顺序消费, 但是一台 Broker 宕机后, 顺序会乱支持顺序消费, 在顺序消 费场景下, 消费失败时消 费队列将会暂停支持顺序消费, 但是一台 Broker 宕机后, 顺序会乱
负载均衡支持支持支持
管理界面无社区有 web console 实现
部署依赖zookeeperNameserverErlang 环境
消费方式保证严格的消费顺序
总结: 优点1、 高吞吐、 低延迟、 高性能 2、 提供多种客户端语言 3、 生态完善, 大数据处理方面的 必备工具模型简单, 接口易用。 在 阿里大规模应用。 目前支 付宝中的余额宝等新兴产 品均使用 rocketmq。 集群 规模大概在 50 台左右, 单 日处理消息上百亿; 性能 非常好, 可以大量堆积消 息在 broker 中; 支持多种 消费, 包括集群消费、 广 播消费等。 开发度较活跃, 版本更新很快。由于 erlang 语言的特性, mq 性能较好; 管理界面较丰富, 在互联网公司也有较大规模的应用; 支持 amqp 协议, 有多种语 言且支持amqp的客户端可 用
总结: 缺点消费者集群数受到分区数的限制 单机 Topic 过多, 性能会明显下降 不支持事务。 容易丢数据。使用者较少, 生态不够 完善, 消息堆积与吞吐量 上与 kafka 还是有差距。 客户端支持 javaErlang 语言难度较大, 集群 不支持动态扩展。 不支持事务, 消息吞吐能 力有限 消息堆积时, 性能会明显 降低。