消息中间件优缺点对比及选型 您所在的位置:网站首页 消息中间件学哪个 消息中间件优缺点对比及选型

消息中间件优缺点对比及选型

2024-01-29 02:46| 来源: 网络整理| 查看: 265

什么是消息队列?(Message queue,简称MQ)

从字面理解就是一个保存消息的一个容器。那么我们为何需要这样一个容器呢? 其实就是为了解耦各个系统,我们来举个例子: 有这么一个简单的场景,系统A负责生成userID,并调用系统B、C。如果系统BC频繁变化是否需要userID参数,则系统A的代码就得不断变化,如果哪天又来了系统DEF……也需要这个参数,则系统A又要加入很多业务逻辑,这样子各他系统之间就容易产生相互影响,另外大量的系统与A发生交互也容易产生问题。 加了消息队列后,A只负责产生userID,至于谁要用这个参数,怎么用?系统A不管。对这个数据感兴趣的系统自己去取用即可,各个系统之间就实现了解耦。而且解耦后,整个服务业变成了一个异步的方式,系统A产生数据后,不用依次调用BCD来累计耗时,各系统可以同时来取用消息队列的数据进行处理,加大吞吐。

消息队列的特点 先进先出:消息队列的顺序在入队的时候就基本已经确定了,一般是不需人工干预的。 发布订阅:发布订阅是一种很高效的处理方式,如果不发生阻塞,基本可以当成是同步操作。 持久化:持久化确保消息队列的使用不只是一个部分场景的辅助工具,而是让消息队列能像数据库一样存储核心的数据。 分布式:在现在大流量、大数据的使用场景下,支持分布式的部署,才能被广泛使用。消息队列的定位就是一个高性能的中间件。 什么是中间件?

非底层操作系统软件,非业务应用软件,不是直接给最终用户使用的,不能直接给客户带来价值的软件统称为中间件。

什么是消息中间件?

关注于数据的发送和接受,利用高效可靠的异步消息传递机制集成分布式系统。

消息中间件的作用(解耦,并发,削峰,异步) 可以在模块、服务、接口等不同粒度上实现解耦 订阅/消费模式可以在数据粒度上解耦 可提高系统的并发能力,集中力量办大事(同步部分),碎片时间做小时(异步部分) 可提高系统可用性,因为缓冲了系统负载 消息中间件的弊端 系统可用性降低:MQ宕机之后整套系统均不能正常使用,如果要保障队列可用,需要额外机制保障(双活或容灾) 系统复杂性提高:存在消息重复消费、消息丢失、消息传递顺序不能保证的问题 降低数据一致性:多个系统消费存在部分成功部分失败的问题,数据不一致了,如要保持强一致性,需要高代价的补偿(分布式事务,对账)

重复消费:系统发了两条,两条都插入了数据库 消息丢失:系统根本没法请求到目标系统 一致性问题:系统要再ABC三个系统都执行成功之后才返回成功,结果AB成功了,C失败了

消息队列的使用场景

消息队列的使用场景有很多,最核心的有三个:解耦、异步、削峰 解耦:一个系统或者一个模块,调用了多个系统或者模块,相互之间的调用很复杂,维护起来很麻烦。此时可以考虑使用消息队列来实现多个系统之间的解耦 异步:系统A接受一个请求,需要在自己本地写库,还需要在系统BCD三个系统写库,同步操作比较费时。 削峰:高峰时段系统接收到的请求缓存到消息队列,供系统根据负载慢慢消化

如秒杀、发邮件、发短信、高并发订单等。 不适合的场景如银行转账、电信开户、第三方支付等。 关键还是要意识到队列的优劣点,然后分析场景是否使用。

MQ的6种工作模式: 简单模式:一个生产者,一个消费者 work模式:一个生产者,多个消费者,每个消费者获取到的消息唯一。 订阅模式:一个生产者发送的消息会被多个消费者获取。 路由模式:发送消息到交换机并且要指定路由key ,消费者将队列绑定到交换机时需要指定路由key topic模式:将路由键和某模式进行匹配,此时队列需要绑定在一个模式上,“#”匹配一个词或多个词,“*”只匹配一个词。 市面上常见的消息中间件

ActiveMQ、RabbitMQ、RocketMQ、kafka

消息中间件的对比 特性 ActiveMQ RabbitMQ RocketMQ kafka 语言 Java Erlang Java Scala 单机吞吐 万 万 十万,支撑高吞吐 十万 可用性 高(主从架构) 高(主从架构) 非常高(分布式架构) 非常高(分布式架构) 管理界面 一般 比较好 一般 一般 时效性 ms us微秒级 ms ms(以内) 功能特性 MQ功能齐全,被大量开源项目使用。 基础erlang开发,所以并发能力很强,性能极其好,延时很低,管理界面很丰富,支持多语言 MQ功能比较完备,扩展性佳,仅适用于Java语言。 只支持主要的MQ功能,像一些消息查询,消息回溯等功能没有提供,毕竟是为了大数据准备的,在大数据领域应用广。 适用场景 主要场景就是解耦和异步调用,较少在大规模吞吐的场景中使用 数据量没有那么大,小公司 目前在阿里被广泛应用在订单、交易、充值、流计算、消息推送、日志流式处理、binglog分发消息等场景。 一般配合大数据类的系统来进行实时数据计算、日志采集等场景。 broker端消息过滤 支持 不支持 可以支持Tag标签过滤和SQL表达式过滤 不支持 消息查询 支持 根据消息id查询 支持Message id或Key查询 不支持 消息回溯 支持 不支持 支持按时间来回溯消息,精度毫秒,例如从一天之前的某时某分某秒开始重新消费消息。 理论上可以支持时间或offset回溯,但是得修改代码。 路由逻辑 基于交换机,可配置复杂路由逻辑 根据topic,可以配置过滤消费 根据topic 持久化 内存、文件、数据库 队列基于内存,只能少量堆积 磁盘,大量堆积 磁盘,大量堆积 顺序消息 支持 不支持 支持 支持 消费并行度 无影响 无影响 顺序消费方式并行度同kafka完全一致;乱序方式并行度取决于消费者的线程数,如topic配置10个队列,10台机器消费,每台机器100个线程,那么并行度为1000。 kafka的消费并行度依赖topic配置的分区数,如分区数为10,那么最多10机器来并行消费(每台机器只能开一个线程),或者一台机器消费(10个线程并行消费)。即消费并行度和分区数一致。 消息可靠性 有较低的概率丢失数据 基本不丢 经过参数优化配置,可以做到 0 丢失 同 RocketMQ 各自的优缺点:

ActiveMQ

采用消息推送方式,所以最适合的场景是默认消息都可在短时间内被消费。数据量越大,查找和消费消息就越慢,消息积压程度与消息速度成反比。 主要场景就是解耦和异步调用,较少在大规模吞吐的场景中使用。

缺点:

吞吐量低。由于ActiveMQ需要建立索引,导致吞吐量下降。 偶尔会有较低概率丢失消息; 不支持消息自动分片机制。这是一个功能缺失,JMS并没有规定消息中间件的集群、分片机制。ActiveMQ初衷并不是为了处理海量消息和高并发请求。如果一台服务器不能承受更多消息,则需要横向拆分。ActiveMQ官方不提供分片机制,需要自己实现。 一般的业务系统要引入MQ,最早大家都用ActiveMQ,但是现在确实大家用的不多了,没经过大规模吞吐量场景的验证,社区也不是很活跃,所以不推荐用这个了。

RabbitMQ

项目开源,社区活跃,管理界面丰富,适用于中小型公司。 erlang开发,队列基于内存,并发高,延时低,基于AMQP协议支持多语言接入。 特有的交换机模式,支持很多复杂场景的消息路由。

缺点:

基于erlang也影响java人员的探索和改造,遇到bug调试起来比较麻烦。 队列只能支持主备,不可分布式扩展,单点问题是硬伤,投递消息如果不在某台虚拟机上,还需要虚拟机转发请求。 队列基于内存,导致无法大量堆积消息。 不支持顺序消息,消息消费失败后会重回队列,打乱顺序。 需要学习比较复杂的接口和协议,学习和维护成本较高。

RocketMQ

阿里双十一经受了许多考验,使用广泛,基于Java语言适合大公司自己改造。 对比Kafka,MQ功能较为完善,额外支持消息查询,消息回溯,消息重试,延迟消息,适合复杂业务场景。 吞吐量相比RabbitMQ高,可用性非常高,分布式架构,扩展性好,支持分布式事务,解耦异步调用。 支持10亿级别的消息堆积,不会因为堆积导致性能下降。 消息可靠性:经过参数优化配置,消息可以做到0丢失。 提供 docker 镜像用于隔离测试和云集群部署。 天生为金融互联网领域而生,对于可靠性要求很高的场景,尤其是电商里面的订单扣款,以及业务削峰,在大量交易涌入时,后端可能无法及时处理的情况。 RoketMQ在稳定性上可能更值得信赖,这些业务场景在阿里双11已经经历了多次考验,如果你的业务有上述并发场景,建议可以选择RocketMQ。

缺点:

社区不够活跃,github上讨论不多,社区可能有黄掉的风险。(目前RocketMQ已捐给Apache) 支持的语言不多,只支持java及c++,其中c++不成熟 没有在 mq 核心中去实现JMS等接口,有些系统要迁移需要修改大量代码

kafka

性能卓越,单机写入TPS约在百万条/秒,最大的优点,就是吞吐量高; 可用性非常高,kafka是分布式的,一个数据多个副本,某个节点宕机,Kafka 集群能够正常工作; 持久性、可靠性: Kafka 能够允许数据的持久化存储,消息被持久化到磁盘,并支持数据备份防止数据丢失,Kafka 底层的数据存储是基于 Zookeeper 存储的,Zookeeper 我们知道它的数据能够持久存储; 优秀的第三方Kafka Web管理界面Kafka-Manager; 在日志领域比较成熟,被多家公司和多个开源项目使用; 主要是用来进行实时数据计算的以及日志收集,现在的项目里面很少用它做消息中间件。

kafka高吞吐率的实现:

顺序读写:kafka将消息读写写入到了分区partition中,而分区消息是顺序读写的。顺序读写要远快于随机读写 零拷贝:生产者、消费者对于kafka中消息的操作都是采用零拷贝实现的 批量发送:kafka允许采用批量消息发送模式 消息压缩:kafka允许对消息集合进行压缩

缺点:

Kafka单机超过64个队列/分区,Load会发生明显的飚高现象,队列越多,Load越高,发送消息响应时间越长。 功能比较简单,主要聚集于日志场景和流计算,对业务型场景支持不够。 使用短轮询方式,实时性取决于轮询间隔时间; 消费失败不支持重试; 支持消息顺序,但是一台代理宕机后,就会产生消息乱序; 社区更新较慢。 对MQ的吞吐量与可用性,可靠性上进行比对 单机吞吐量

ActiveMQ、RabbitMQ单机吞吐量为万级; RocketMQ、Kafka可以达到10万级的吞吐量。

topic数量对吞吐量的影响

RocketMQ和Kafka会受到topic数量的影响。 Kafka的topic从几十到几百个增加的时候,吞吐量会大幅度下降。在同等机器下,kafka尽量保证topic数量不要过多,如果需要支撑大规模的topic,需要增加更多的机器资源。 因为Kafka的每个Topic、每个分区都会对应一个物理文件。当Topic数量增加时,消息分散的落盘策略会导致磁盘IO竞争激烈成为瓶颈。 RocketMQ的topic 可以达到几百/几千的级别,吞吐量会有较小幅度的下降,这是 RocketMQ 的一大优势,在同等机器下,可以支撑大量的 topic。 RocketMQ所有的消息是保存在同一个物理文件中的,Topic和分区数对RocketMQ也只是逻辑概念上的划分,所以Topic数量的增加对RocketMQ的性能不会造成太大的影响。

可用性

ActiveMQ和RabbitMQ在高可用上采用主从架构实现的高可用。 RocketMQ和Kafka采用的分布式架构来保证高可用性。

消息可靠性

ActiveMQ有较低的概念丢失数据。 RabiitMQ基本上不会丢, 但是还是无法得到保证。 RocketMQ与Kafka经过优化配置,可以做到0丢失。

综上,有如下建议:

首先,个人不推荐使用ActiveMQ,社区不活跃,并且没有经过大规模的吞吐量场景的验证。 你永远无法想象MQ消息丢失或者宕机带来的影响有多巨大。

RabbitMQ使用Erlang开发,对JAVA工程师来说较难深入的研究和掌握,对公司而言,几乎是处于不可控的状态。 但是, RabbitMQ开源社区一直都在活跃,并且有稳定的支持。

RocketMQ是阿里的开源产品(但是,阿里自己的内部版本是商业版本,在阿里云可以直接购买服务),阿里的开源产品,如果有使用的同学应该会有较大的感触,有可能会突然黄掉!所以,如果使用RocketMQ的话,需要对自己公司的技术能力有一定的要求。

Kafka主要支持简单的MQ功能,在大数据领域的实时计算以及日志采集被大规模使用。 Kafka目前无法支持如延迟队列(需要额外的业务处理支持), 在较新的版本只支持了事务消息。 但是整体而言,支持的业务场景较少。

总体而言: 中小型公司,技术实力较为一般,技术挑战不是特别高,用 RabbitMQ 是不错的选择; 大型公司,基础架构研发实力较强,用 RocketMQ 是很好的选择。(当然,需要对RocketMQ 进行一定的改造。 如对延迟消息的控制级别)。 如果是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。

查看更多关于消息队列选型及原理

消息队列常见问题 如何保证消息队列的高可用?

RabbitMQ基于主从的高可用,分为单机模式、普通集群模式、镜像集群模式三种 普通集群模式:多台服务器部署RabbitMQ,一个queue只会保存在一个节点上,其他节点只会同步该queue的元数据,当请求从其他节点获取该queue的数据时,该节点会再次去存储该queue的节点上拉取所需数据。这样就导致使用时要么固定使用其中一个节点,要么随机节点再需要的时候拉取数据。如果存放数据的节点宕机了,其他节点就无法拉取数据,如果开启了消息持久化让RabbitMQ落地存储消息就不一定会丢失消息,得等这个实例恢复后才能继续从这个queue拉取数据。 镜像集群模式(高可用模式):创建的queue会同步到所有实例上来实现高可用。这样会带来同步数据的开销和扩展性降低(扩展机器会导致新增的机器同步queue增加更多同步数据的开销);配置方式可通过控制台配置。

Kafka的高可用:分布式消息队列 Kafka由多个broker组成,每个broker是一个节点,创建的一个topic划分为多个partition,每个partition可放在不同的broker上,每个partition只存放一部分数据。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有