RocketMQ由入门到放弃(一)

1、MQ介绍

1.1、什么是消息队列

消息队列(Message Queue)是一种进程间通信或同一进程的不同线程间的通信方式。通俗点来讲的话,消息队列就是一个存放消息的容器,是一种“先进先出”的数据结构

1.2、什么时候需要消息队列

1.2.1、异步处理(短信通知,发送邮件,终端状态推送,App推送等)

有些业务不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的时候再去处理它们。
复制代码

场景说明:用户注册后,需要发送注册的邮件和注册的短信。

传统的做法有两种:1.串行的方式;2.并行的方式

(1)、 串行的方式: 将注册信息写入数据库成功后,发送注册邮件,再发送注册短信。以上三个任务全部完成后,返回给客户端。

(2)、 并行方式: 将注册信息写入数据库成功后,发送注册邮件的同时,发送注册短信。以上三个任务完成后,返回给客户端。 与串行的差别是: 并行的方式可以提高处理的时间

假设三个业务节点每个使用50毫秒钟,不考虑网络等其他开销,则串行方式的时间是150毫秒,并行的时间可能是100毫秒。

因为CPU在单位时间内处理的请求数是一定的,假设CPU1秒内吞吐量是100次。则串行方式1秒内CPU可处理的请求量是7次(1000/150)。并行方式处理的请求量是10次(1000/100)

引入消息队列,将不是必须的业务逻辑,异步处理。改造后的架构如下:

按照以上约定,用户的响应时间相当于是注册信息写入数据库的时间,也就是50毫秒。注册邮件,发送短信写入消息队列后,直接返回,因此写入消息队列的速度很快,基本可以忽略,因此用户的响应时间可能是50毫秒。因此架构改变后,系统的吞吐量提高到每秒20 QPS比串行提高了3倍,比并行提高了2倍

1.2.2、应用解耦

场景说明:用户下单后,订单系统需要通知库存系统和支付系统。传统的做法是,订单系统调用库存系统和支付系统的接口。如下图

传统模式的缺点:

  • 假如库存系统或者是支付无法访问,则订单减库存将失败或者是支付失败,从而导致订单失败

  • 订单系统与库存系统耦合

如何解决以上问题呢?引入应用消息队列后的方案,如下图:

订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功

库存系统:订阅下单的消息,采用拉/推的方式,获取下单信息,库存系统根据下单信息,进行库存操作

库存系统:订阅下单的消息,采用拉/推的方式,获取下单信息,支付系统根据下单信息,进行支付操作

假如:在下单时库存系统或支付系统不能正常使用。也不影响正常下单,因为下单后,订单系统写入消息队列就不再关心其他的后续操作了。实现订单系统与库存系统,订单系统和支付系统的应用解耦。

1.2.3、流量削峰

流量削锋也是消息队列中的常用场景,一般在秒杀或团抢活动中使用广泛

应用场景:秒杀活动,一般会因为流量过大,导致流量暴增,应用挂掉。为解决这个问题,一般需要在应用前端加入消息队列。

应用系统如果遇到系统请求流量的瞬间猛增,有可能会将系统压垮。有了消息队列可以将大量请求缓存起来,分散到很长一段时间处理,这样可以大大提到系统的稳定性和用户体验。

一般情况,为了保证系统的稳定性,如果系统负载超过阈值,就会阻止用户请求,这会影响用户体验,而如果使用消息队列将请求缓存起来,等待系统处理完毕后通知用户下单完毕,这样总不能下单体验要好。

处于经济考量目的:

业务系统正常时段的QPS如果是1000,流量最高峰是10000,为了应对流量高峰配置高性能的服务器显然不划算,这时可以使用消息队列对峰值流量削峰

1.2.4、内容分发

通过消息队列可以让数据在多个系统更加之间进行流通。数据的产生方不需要关心谁来使用数据,只需要将数据发送到消息队列,数据使用方直接在消息队列中直接获取数据即可

1.3 MQ的优点和缺点

优点:异步处理、解耦、削峰、数据分发

缺点包含以下几点:

  • 系统可用性降低

    系统引入的外部依赖越多,系统稳定性越差。一旦MQ宕机,就会对业务造成影响。

    如何保证MQ的高可用?

  • 系统复杂度提高

    MQ的加入大大增加了系统的复杂度,以前系统间是同步的远程调用,现在是通过MQ进行异步调用。

    如何保证消息没有被重复消费?怎么处理消息丢失情况?那么保证消息传递的顺序性?

  • 一致性问题

    A系统处理完业务,通过MQ给B、C、D三个系统发消息数据,如果B系统、C系统处理成功,D系统处理失败。

    如何保证消息数据处理的一致性?

1.4 选择消息队列的基本标准

虽然这些消息队列在功能和特性方面各有优劣,但我们在选择的时候要有一个基本标准。

首先,必须是 开源的产品 。开源意味着,如果有一天你使用的消息队列遇到了一个影响你系统业务的 Bug,至少还有机会通过修改源代码来迅速修复或规避这个 Bug,解决你的系统的问题,而不是等待开发者发布的下一个版本来解决。

其次,这个产品必须是近年来比较流行并且 有一定社区活跃度 的产品。流行的好处是,只要使用场景不太冷门,遇到 Bug 的概率会非常低,因为大部分遇到的 Bug,其他人早就遇到并且修复了。在使用过程中遇到的一些问题,也比较容易在网上搜索到类似的问题,然后很快的找到解决方案。还有一个优势就是,流行的产品与周边生态系统会有一个比较好的集成和兼容。

最后,作为一款及格的消息队列,必须具备的几个特性包括:

  • 消息的可靠传递 :确保不丢消息;
  • Cluster :支持集群,确保不会因为某个节点宕机导致服务不可用,当然也不能丢消息;
  • 性能 :具备足够好的性能,能满足绝大多数场景的性能要求。

接下来看一下有哪些符合上面这些条件,可供选择的开源消息队列。

1.4.1 RabbitMQ

首先,我们来看下消息队列 RabbitMQ。RabbitMQ 于 2007 年发布,是使用 Erlang 编程语言编写的,最早是为电信行业系统之间的可靠通信设计的,也是少数几个支持 AMQP 协议的消息队列之一。

RabbitMQ:轻量级、迅捷,它的宣传口号,也很明确地表明了 RabbitMQ 的特点:Messaging that just works,开箱即用的消息队列。也就是说,RabbitMQ 是 一个相当轻量级的消息队列,非常容易部署和使用

RabbitMQ 一个比较有特色的功能是 支持非常灵活的路由配置 ,和其他消息队列不同的是,它在生产者(Producer)和队列(Queue)之间增加了一个 Exchange 模块,可以理解为交换机。

Exchange 模块的作用和交换机非常相似,根据配置的路由规则将生产者发出的消息分发到不同的队列中。路由的规则也非常灵活,甚至可以自己来实现路由规则。如果正好需要这个功能,RabbitMQ 是个不错的选择。

RabbitMQ 的客户端支持的编程语言大概是所有消息队列中最多的。

接下来说下 RabbitMQ 的几个问题:

  • RabbitMQ 对消息堆积的支持并不好,当大量消息积压的时候,会导致 RabbitMQ 的性能急剧下降。

  • RabbitMQ 的性能是这几个消息队列中最差的,大概每秒钟可以处理几万到十几万条消息。如果应用对消息队列的性能要求非常高,那不要选择 RabbitMQ。

  • RabbitMQ 使用的编程语言 Erlang,扩展和二次开发成本高。

1.4.2 RocketMQ

RocketMQ 是阿里巴巴在 2012 年开源的消息队列产品,用 Java 语言实现,在设计时参考了 Kafka,并做出了自己的一些改进,后来捐赠给 Apache 软件基金会,2017 正式毕业,成为 Apache 的顶级项目。RocketMQ 在阿里内部被广泛应用在订单,交易,充值,流计算,消息推送,日志流式处理,Binglog 分发等场景。经历过多次双十一考验,它的性能、稳定性和可靠性都是值得信赖的。

RocketMQ 有着不错的性能,稳定性和可靠性, 具备一个现代的消息队列应该有的几乎全部功能和特性 ,并且它还在持续的成长中。

RocketMQ 有 非常活跃的中文社区 ,大多数问题可以找到中文的答案。RocketMQ 使用 Java 语言开发,源代码相对比较容易读懂, 容易对 RocketMQ 进行扩展或者二次开发

RocketMQ 对在线业务的响应时延做了很多的优化,大多数情况下可以做到 毫秒级的响应 ,如果你的应用场景很在意响应时延,那应该选择使用 RocketMQ。

RocketMQ 的性能比 RabbitMQ 要高一个数量级, 每秒钟大概能处理几十万条消息

RocketMQ 的劣势是与周边生态系统的集成和兼容程度不够。

1.4.3 Kafka

Apache Kafka 是一个 分布式消息发布订阅系统 。它最初由 LinkedIn 公司基于独特的设计实现为一个分布式的日志提交系统,之后成为 Apache 项目的一部分。

在早期的版本中,为了获得极致的性能,在设计方面做了很多的牺牲,比如不保证消息的可靠性,可能会丢失消息,也不支持集群,功能上也比较简陋,这些牺牲对于处理海量日志这个特定的场景都是可以接受的。

但是,随后几年 Kafka 逐步补齐了这些短板,当下的 Kafka 已经发展为一个非常成熟的消息队列产品,无论在数据可靠性、稳定性和功能特性等方面都可以满足绝大多数场景的需求。

Kafka 与 周边生态系统的兼容性是最好的没有之一 ,尤其在大数据和流计算领域,几乎所有的相关开源软件系统都会优先支持 Kafka。

Kafka 性能高效、可扩展良好并且可持久化。它的分区特性,可复制和可容错都是不错的特性。

Kafka 使用 Scala 和 Java 语言 开发,设计上大量使用了批量和异步的思想,使得 Kafka 能做到超高的性能。Kafka 的性能,尤其是异步收发的性能,是三者中最好的,但与 RocketMQ 并没有量级上的差异,大约 每秒钟可以处理几十万条消息

在有足够的客户端并发进行异步批量发送,并且开启压缩的情况下,Kafka 的极限处理能力可以超过每秒 2000 万条消息。

但是 Kafka 异步批量的设计带来的问题是,它的同步收发消息的响应时延比较高,因为当客户端发送一条消息的时候,Kafka 并不会立即发送出去,而是要等一会儿攒一批再发送,在它的 Broker 中,很多地方都会使用这种先攒一波再一起处理的设计。当你的业务场景中,每秒钟消息数量没有那么多的时候,Kafka 的时延反而会比较高。所以,Kafka 不太适合在线业务场景。

1.5 各种MQ产品的比较

常见的MQ产品包括RabbitMQ、RocketMQ、Kafka。

特性 RabbitMQ RocketMQ Kafka
开发语言 erlang java scala
单机吞吐量 万级 十万级 十万级
时效性 us级 ms级 ms级以内
可用性 高(主从架构) 很高(分布式架构) 很高(分布式架构)
可靠性 基本不丢 经过参数优化配置,可以做到 0 丢失 经过参数优化配置,可以做到 0 丢失
功能特性 基于 erlang 开发,并发能力很强,性能极好,延时很低 MQ 功能较为完善,还是分布式的,扩展性好 只支持主要的MQ的功能, 像一些消息队列的信息查询,消息回溯等功能没有提供, 毕竟是为大数据准备的,在大数据领域应用广。

中小型公司,技术实力较为一般,技术挑战不是特别高,用 RabbitMQ 是不错的选择; 大型公司 (我们公司肯定是要往这个方向发展的),基础架构研发实力较强,用 RocketMQ 是很好的选择。

如果是 大数据领域 的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。

稀土掘金
我还没有学会写个人说明!
上一篇

车头配“加特林” 007同款阿斯顿·马丁座驾量产交付

下一篇

索尼发布大量游戏厂商年末节日贺卡

你也可能喜欢

评论已经被关闭。

插入图片