初识消息队列

1. 什么叫消息队列

消息(Message)是指在应用间传送的数据。消息可以非常简单,比如只包含文本字符串,也可以更复杂,可能包含嵌入对象。

消息队列(Message Queue)是一种应用间的通信方式,消息发送后可以立即返回,由消息系统来确保消息的可靠传递。消息发布者只管把消息发布到 MQ 中而不用管谁来取,消息使用者只管从 MQ 中取消息而不管是谁发布的。这样发布者和使用者都不用知道对方的存在。

2.什么时候需要消息队列

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

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

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

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

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

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

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

2.1 应用解耦

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

传统模式的缺点:

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

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

如何解决以上问题呢?引入应用消息队列

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

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

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

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

2.3、流量削峰

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

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

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

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

处于经济考量目的:

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

2.4、内容分发

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

3 MQ的优点和缺点

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

缺点包含以下几点:

  • 系统可用性降低

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

    如何保证MQ的高可用?

  • 系统复杂度提高

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

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

  • 一致性问题

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

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

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。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值