MQ消息队列(应用场景,产品对比)

一、什么是消息队列(MQ)

MessageQueue 是一个广泛应用在互联网项目中且非常重要的技术, MessageQueue 通常被用来解决在高并发压力下类似于流量削峰、服务解耦、消息通讯、最终消息一致性等这样的问题。

二、什么场景下使用MQ呢?

MQ 可应用在多个领域,包括异步通信解耦、企业解决方案、金融支付、电信、电子商务、快递物流、广告营销、社交、即时通信、手游、视频、物联网、车联网等。

从应用功能上来讲。例如:

  • 日志监控,作为重要日志的监控通信管道,将应用日志监控对系统性能影响降到最低。
  • 消息推送,为社交应用和物联网应用提供点对点推送,一对多广播式推送的能力。
  • 金融报文,发送金融报文,实现金融准实时的报文传输,可靠安全。
  • 电信信令,将电信信令封装成消息,传递到各个控制终端,实现准实时控制和信息传递。

从功能角度考虑:

  • MQ 在实际应用中常用的使用场景主要有异步处理,应用解耦,流量削锋和消息通讯四个场景

2.1 异步处理

场景说明:用户注册后,需要发注册邮件和注册短信。传统的做法有两种:

1.正常串行的方式

  • 注册信息写入数据库
  • 发送注册邮件
  • 发送注册短信

总共耗时150ms

2.并行方式(开启异步线程)

  • 注册信息写入数据库
  • 注册邮件+短信

总共耗时100ms

假设三个业务节点每个使用 50 毫秒钟,不考虑网络等其他开销,则串行方式的时间是 150 毫秒,并行的时间可能是 100 毫秒。 因为 CPU 在单位时间内处理的请求数是一定的,假设 CPU1 秒内吞吐量是 100 次。则串行方式 1 秒内 CPU 可处理的请求量是 7 次(1000/150)。并行方式处理的请求量是 10 次(1000/100)

小结:如以上案例描述,传统的方式系统的性能(并发量,吞吐量,响应时间)会有瓶颈。如何解决这个问题呢?

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

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

当然了,也不光注册这个场景,还有上传文件啊,解析Excel啊,都可以考虑引入队列,然后搞一个传输中心就可以了。

2.2 应用解耦

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

在这里插入图片描述

传统模式的缺点:假如库存系统无法访问,则订单减库存将失败,从而导致订单失败,订单系统与库存系统耦合

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

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

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

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

2.3 流量削峰

流量削锋也是消息队列中的常用场景,一般在秒杀或抢够活动中使用广泛。
应用场景:秒杀活动,一般会因为流量过大,应用系统配置承载不了这股瞬间流量,导致系统直接挂掉,即传说中的“宕机”现象。为解决这个问题,我们会将那股巨大的流量拒在系统的上层,即将其转移至 MQ 而不直接涌入我们的接口,此时MQ起到了缓冲作用。

2.4 日志处理

日志处理是指将消息队列用在日志处理中,比如 Kafka 的应用,解决大量日志传输的问题。架构简化如下

在这里插入图片描述

  • 日志采集客户端,负责日志数据采集,定时写入kafka队列

  • kafka消息队列,负责日志数据的接收,储存和转发

  • 日志处理应用:订阅并消费kafka数据

  • 常用的日志收集架构有:

  • ELK/EFK

三、MQ产品对比

目前主流的MQ主要有:

  • RabbitMQ
  • RocketMQ
  • kafka
  • Activemq

3.1 MQ对比

**MQ**
**描述**
RabbitMQ
erLang开发(高并发语音),对消息堆积的支持不算太好,当大量消息积压的时候,会导致Rabbit性能下降。每秒钟可以处理几万到几十万条消息。
RocketMQ
java开发,面向互联网集群化功能丰富,对在线业务的响应时延做了很多的优化,大多数情况。而且由于是java开发,如果想进行定制化扩展也比较方便
Kafka
Scala开发,面向日志功能丰富,性能最高。当你的业务场景中,每秒钟消息数量没有那么多的时候,kafka的时延反而会比较高,所以,Kafka不太适合在线业务场景。
Activemq
java开发,简单,稳定,性能不如前面三个。小型系统用也ok,但是不推荐。

3.2 主流MQ的优缺点

 

  RabbitMQ RocketMQ Kafka Activemq
协议 AMQP AMQP 自行设计 AMQP
跨语言 支持 支持 支持 支持
优点 单机吞吐量: 万级 健壮、稳定、医用、跨平台、支持多种语言; 功能支持: MQ功能完备 高扩展性: 支持事务 单机吞吐量:十万级 可用性: 非常高,分布式 架构: 消息可靠性高 功能支持:MQ功能完备 高扩展性:支持事务 单机吞吐量:百万级 可用性:分布式的非常高 依赖ZK可动态扩展节点高性能高吞吐,消息可指定追溯 单机吞吐量:万级 可用性:非常高 功能支持: MQ功能完备 高扩展性
缺点 Elang语言难度大,很难扩展,研发人员较少 目前只支持java及c++; 严格的顺序机制,不支持消息优先级,不支持标准协议 项目比较陈旧,官方社区在5.X之后对其维护越来越少
综合评价 适用于稳定性要求优先的企业级应用 阿里系,国内互联网公司使用居多 在日志和大数据方向使用较多 小型系统比较适用,但是因为维护越来越少,建议不用

中小型软件公司,建议选 RabbitMQ,一方面,erlang 语言天生具备高并发的特性,而且他的管理界面用起来十分方便。正所谓,成也萧何,败也萧何!他的弊端也在这里,虽然RabbitMQ 是开源的,然而国内有几个能定制化开发 erlang 的程序员呢?所幸,RabbitMQ的社区十分活跃,可以解决开发过程中遇到的 bug,这点对于中小型公司来说十分重要。不考虑 rocketmq 和 kafka 的原因是,一方面中小型软件公司不如互联网公司,数据量没那么大,选消息中间件,应首选功能比较完备的,所以 kafka 排除。可以考虑阿里的 rocketmq.

大型软件公司,根据具体使用在 rocketMq 和 kafka 之间二选一。一方面,大型软件公司,具备足够的资金搭建分布式环境,也具备足够大的数据量。针对 rocketMQ,大型软件公司也可以抽出人手对 rocketMQ 进行定制化开发,毕竟国内有能力改 JAVA 源码的人,还是相当多的。至于 kafka,根据业务场景选择,如果有日志采集功能,肯定是首选 kafka 了。具体该选哪个,看使用场景。

我们在进行中间件选型时,一般都是通过下面几点来进行产品选型的:

 1)性能
2)功能支持程度
3)开发语言(团队中是否有成员熟悉此中间件的开发语言,市场上此种语言的开发人员是否好招)
4)有多少公司已经在生产环境上实际使用过,使用的效果如何
5)社区的支持力度如何
6)中间件的学习程度是否简单、文档是否详尽
7)稳定性
8)集群功能是否完备

如果从以上 8 点来选型一个消息队列,作为一名熟悉 java 的程序员,当遇到重新选择消息队列的场景时,我会毫不犹豫的选型 rocketmq,除了监控管理功能不友好外,从其它方面来说,它真的是一款非常优秀的消息队列中间件。而且如果你的项目是用java编写的话,使用rocketmq在排错以及优化上,都可以自行进行定制。


作者:塔哥哥要学习
链接:https://juejin.cn/post/6896744901665521677
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
posted @ 2020-11-19 18:49  Java团长  阅读(1735)  评论(0编辑  收藏  举报