干货!十分钟搞懂消息队列的选型

大家好,我是程序员史迪仔。

消息队列重要吗?有必要学吗?当然重要!

想必你在面试或者工作的过程中,被问过以下问题:

(1)为什么你们项目要用消息队列?

(2)用了消息队列后有什么好处?

(3)消息队列有 ActiveMQ、ZeroMQ、MetaMQ、RabbitMQ、RocketMQ、Kafka等,你是怎么选型的?

(4)你能对比下 RabbitMQ、RocketMQ、Kafka 吗?

如果你只会回答 ”我只会用这个消息队列“、”公司用的是这个消息队列“ 等等,可以肯定的告诉你将会被 pass 掉。

技术选型是开发工作前最重要的,也是最体现技术的环节。

目前主流的消息队列分别为 Kafka、RabbitMQ、RocketMQ 和 ActiveMQ。

这篇文章重点介绍这四种消息队列的概述、对比和选型,不深入研究每种队列内部的实现原理。 alt

消息队列是什么?

消息队列是在消息的传输过程中保存消息的容器,简单点理解就是传递消息的队列,具备先进先出的特点,一般用于异步、解耦、流量削锋等问题,实现高性能、高可用、高扩展的架构。一个消息队列可以被一个或多个消费者消费,一般包含以下元素:

  • Producer:消息生产者,负责产生和发送消息到 Broker。
  • Broker:消息处理中心,负责消息存储、确认、重试等,一般其中会包含多个 Queue。
  • Consumer:消息消费者,负责从 Broker 中获取消息,并进行相应处理。

消息队列应用场景

常见的消息队列使用场景有 6 个:

  • 应用解耦:消息队列减少了服务之间的耦合性,不同的服务可以通过消息队列进行通信,而不用关心彼此的实现细节。
  • 异步处理:消息队列本身是异步的,它允许接收者在消息发送很长时间后再取回消息。
  • 流量削锋:当上下游系统处理能力存在差距的时候,利用消息队列做一个通用的”载体”,在下游有能力处理的时候,再进行分发与处理。
  • 日志处理:将消息队列用在日志处理中,比如 Kafka 的应用,解决大量日志传输的问题。
  • 消息通讯:消息队列一般都内置了高效的通信机制,因此也可以用在纯消息通讯,比如实现聊天室等。
  • 消息广播:如果没有消息队列,每当一个新业务方接入,都要接入一次新接口。有了消息队列,我们只需要关心消息是否送达了队列,至于谁订阅,是下游的事,无疑极大地减少了开发和联调的工作量。

比较核心的有 3 个:解耦异步削峰,下面着重讲下:

解耦

假设在没有消息队列的情况下,现在有上游服务 A 用来发布消息,下游服务 B、C 用来接收服务 A 的消息。但随着业务需要,现在有服务 D、E、F 需要接收服务 A 的消息,那么就出现问题了,每次新加入服务都要改一次代码,可想而知这是极大的工作量。

alt

如果引入消息队列,那就好办了,只需要下游服务自己订阅消息队列,而无需改动服务 A 的代码。

alt

异步

先来看没有消息队列的场景下。

服务 A 的某个接口接收到请求,分别需要在服务A、服务B、服务C、服务D进行写库。假设用户发起请求到服务 A 耗时 10ms,自己写库需要 50ms,在服务 B 写库需要 250ms,在服务 C 写库需要 300ms,在服务 D 写库需要400ms,在没有消息队列的情况下,也就是同步操作,总耗时会是 10 + 50ms + 250ms + 300ms + 400ms = 1.01s。用户发送个请求,结果感觉有点卡顿,响应的非常慢,任谁都是很难忍受的。

alt

如果使用了消息队列,那么服务 A 只需要把对服务A、B、C、D 进行写库的操作分别放进四个消息队列,假如用户发起请求到服务器耗时是10ms,发送消息到四个消息队列的耗时是10ms,那么总耗时就是 20 ms 。用户点击了按钮后立马返回,没有卡顿现象,体验效果就会有极大的提升了。

alt 一般接口同步处理时间很长,不能通过水平扩容来解决,且业务场景允许异步,就可以使用异步解决,比如文件上传下载受限于用户的网络带宽因素,扩容也无用,以及上述同步操作耗时长等情况,都可以先放进消息队列,等服务再进行拉取消费。

削峰

在淘宝双十一活动日,特别是 0 点的秒杀活动高峰期时,接口流量会飙升,远远高于平时,就像一个山峰,没有做好处理的话,在高峰期数据库就可能被流量打死,从而导致整个服务奔溃。如果为了在高峰期能顶住流量而常备高流量设备,会有极大的成本浪费。如果是在要高峰期前进行临时服务扩容,很可能会出现许多扩容问题,没有那么简单。

使用消息队列的话,就可以将高峰期过多的流量请求放进消息队列,等高峰期过后,服务再慢慢进行处理,就不会出现峰值流量了,而是一个相对平稳的状态。

举个例子:

  • 大量的用户在中午高峰期的时候,每秒有 4k 个请求,那么每秒就有 4k 个请求放到 MQ 里。

  • 服务A 每秒只能处理 2k 个请求,因为 Mysql 每秒最多处理 2k 个请求。

  • 服务A 就每秒从 MQ 拉取 2k 个请求进行处理,不会超过自己每秒能处理的最大请求量,所以高峰期服务 A 就不会挂掉。

  • 对于MQ,每秒 4k 个请求进来,但是却只有 2k 个请求出去,导致在高峰期 1h 内可能有几十万的请求积压在 MQ 中。这个短暂的高峰期请求积压是可以接受的,因为过了这个时间点,每秒就 100 个请求进 MQ,但这时服务 A 还是会按照每秒 2k 的速度处理 MQ 积压的请求。

  • 所以,高峰期一过,服务 A 就会快速的将 MQ 积压的消息处理掉。

alt

消息队列模型

  • 点对点模式:多个生产者可以向同一个消息队列发送消息,一个消息只能被一个消费者消费,在被消费成功后,这条消息会被移除。如果消费者处理消息失败了,那么这条消息会重新被消费。

    alt
  • 发布/订阅模式:单个消息可以被多个订阅者并发的获取和处理。多个生产者可以将多个消息写到同一个 Topic 中,被同一个消费者消费。

    alt

消息队列对比

消息队列有 ActiveMQ、ZeroMQ、RabbitMQ、RocketMQ、Kafka,其中 ZeroMQ 太过轻量,主要用于学习,实际是不会应用到生产,所以主要对比 Kafka、RocketMQ、RabbitMQ、ActiveMQ 这四种 MQ。

特性KafkaRocketMQRabbitMQActiveMQ
单机吞吐量10万级别,吞吐量高是kafka最大的优点10万级,RocketMQ 也是可以支撑高吞吐的 MQ万级,吞吐量比RocketMQ和Kafka要低了一个数量级万级,吞吐量比RocketMQ和Kafka要低了一个数量级
支持主题数百级,topic 达到百级时吞吐量会大幅度下降,要尽量保证 topic 数量不要过多,否则需要增加更多机器资源千级,topic 达到千级时吞吐量会有较小幅度的下降。可以支撑大量 topic 是 RocketMQ 的一大优点百万级千级
消息顺序性分区有序有序有序有序
消息重复至少一次,最多一次至少一次,最多一次至少一次至少一次
时效性ms级ms级微秒级,RabbitMQ的一大优点ms级
可用性非常高,分布式架构,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用非常高,分布式架构高,基于主从架构实现高可用性高,基于主从架构实现高可用性
消息可靠性经过参数优化配置,理论上消息可以做到0丢失经过参数优化配置,理论上消息可以做到0丢失有较低的概率丢失数据有较低的概率丢失数据
消息回溯支持(按offset回溯)支持(按时间回溯)不支持不支持
功能支持功能较为简单,主要支持简单的MQ功能,在大数据领域的实时计算以及日志采集被大规模使用,是事实上的标准MQ功能较为完善,还是分布式的,扩展性好基于erlang开发,所以并发能力很强,性能极其好,延时很低MQ领域的功能极其完备
伸缩性高伸缩性,每个主题(topic)包含多个分区(partition),主题中的分区可以分布在不同的主机(broker)中高伸缩性,灵活的分布式横向扩展部署架构,整体架构和 kafka 很像一般
管理界面普通完善普通普通
持久化消息可以持久化到磁盘消息可以持久化到磁盘持久化不好,可以持久化到内存、文件可以持久化到内存、文件、数据库
消息路由不支持不支持支持
语言支持支持多语言,Java优先支持Java、C++,但C++不成熟支持几乎所有最受欢迎的编程语言:Java,C,C ++,C#,Ruby,Perl,Python,PHP等支持多语言,Java优先
社区活跃度一般

消息队列选型

Kafka 和 RocketMQ 都支持 10w 级别的高吞吐量。

Kafka 一开始的目的就是用于日志收集和传输,适合有大量数据产生的互联网业务,特别是大数据领域的实时计算、日志采集等场景,用 Kafka 绝对没错,社区活跃度高,业内标准。

RocketMQ 特别适用于金融互联网领域这类对于可靠性要求很高的场景,比如订单交易等,而且 RocketMQ 是阿里出品的,经历过那么多次淘宝双十一的考验,大品牌,在稳定性值得信赖。但如果阿里不再维护这个技术了,社区有可能突然黄掉的风险。因此如果公司对自己的技术实力有自信,基础架构研发实力较强,推荐用 RocketMQ。

RabbitMQ 适用于公司对外提供能力,可能会有很多主题接入的中台业务场景,毕竟它是百万级主题数的。它的时效性是毫秒级的,但实际毫秒级和微秒级在感知上没有什么太大的区别,所以它的这一大优点并不太会作为考量标准。同时,它的功能是比较完善的,开源社区活跃度高,能解决开发中遇到的bug,所以万级别数据量业务场景的小公司可以优先选择功能完善的RabbitMQ。它的缺点就是用 Erlang 语言编写,所以很多开发人员很难去看懂源码并进行二次开发和维护,也就是说对于公司来说可能处于不可控的状态。

ActiveMQ 现在很少有人用,没怎么经过大规模吞吐量场景的考验,社区不怎么活跃,官方社区现在对 ActiveMQ 5.x 维护也越来越少,所以不推荐使用。

最后

本篇文章给大家介绍了消息队列是什么、消息队列的应用场景、模型、对比和选型,其实就是围绕着文章开头提到的问题进行分析。

在面试时被问到技术选型,可以结合自己参与过的项目业务场景和消息队列特性进行分析,体现自己知识的全面性和思考分析问题能力。

在实际工作中,就得要结合公司业务场景、团队技术栈、人力成本、MQ优缺点、活跃度等等进行综合分析,选出合适的方案。

不认真进行技术调研、分析思考,随便选技术进行使用,无疑是在给自己和公司挖坑。

OK, 今天的干货分享到这结束!

欢迎关注公众号【程序员史迪仔】,分享后台领域干货。

alt

本文由 mdnice 多平台发布

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值