深入剖析MQ(消息队列):解耦、削峰、异步
  2HyDHh3MOg71 2023年11月13日 22 0

1.同步和异步介绍

在了解什么事消息队列之前,我们要先知道同步和异步通讯的区别,我们从以下两方面介绍MQ:

  • 同步和异步通讯
  • 什么使用MQ

1.1. 同步和异步通讯

微服务之间的通讯方式有同步和异步两种方式:

  • 同步通讯实现方式OpenFegin,就像打电话,实时响应,同时不能和两个人通话
  • 异步通讯实现方式MQ(消息队列),就像发邮件,或者微信聊天,可以同时和多人交流,并且不需要对方马上回复

深入剖析MQ(消息队列):解耦、削峰、异步_消息队列

两种方式各有优劣,同步方式,需要立即得到响应,但是不能同时和多个微服务进行通讯,异步方式可以同时和多个微服务进行交互,但是响应会有延迟。

1.1.1.同步通讯

通过上面介绍我们已经知道,SpringCloud中的OpenFegin技术就是同步通讯方式,虽然OpenFegin调用微服务可以进行实时响应,但是也存在以下很多问题:

  • 耦合度高:每一次加入新的需求,都需要修改原有代码
  • 性能下降: 调用者需要等待服务提供者响应,如果服务链过长,那么每次响应时间等于调用时间之和
  • 资源浪费: 服务链中的每个服务等待响应过程,不能释放请求,就会占用资源,在高并发情况下就会形成资源浪费
  • 级联失败: 如果服务提供者存在问题,那么所有调用该服务的调用者都会出现问题,最终可能导致整个微服务集群出现故障

总结

同步调用的优点:

  • 时效性较强,可以立即得到结果

同步调用的问题:

  • 耦合度高
  • 性能和吞吐能力下降
  • 有额外的资源消耗
  • 有级联失败问题

1.1.2. 异步通讯

异步通讯,我们今天要介绍的MQ技术就是常用实现方式之一,他避免了同步调用出现的问题。

举例说明:

当小伙伴在京东购买商品,在我们支付的时候,同时会异步调用订单服务修改订单状态,调用库存服务减少库存个数,同时也调用物流服务准备发货。

我们可以将支付服务看做事件发布者(publisher),在支付完成后只需要发布一个支付成功的事件(event),事件中带上订单id。订单服务、库存服务和物流服务看做事件订阅者(Consumer),订阅支付成功的事件,监听到事件后完成自己业务即可。

为了解除事件发布者与订阅者之间的耦合,两者并不是直接通信,而是有一个中间人(Broker)。发布者发布事件到Broker,不关心谁来订阅事件。订阅者从Broker订阅事件,不关心谁发来的消息。

深入剖析MQ(消息队列):解耦、削峰、异步_消息队列_02

Broker 是一个像数据总线一样的东西,所有的服务要接收数据和发送数据都发到这个总线上,这个总线就像协议一样,让服务间的通讯变得标准和可控。

好处

  • 吞吐量提升:无需等待订阅者处理完成,响应更快速
  • 故障隔离:服务没有直接调用,不存在级联失败问题
  • 调用间没有阻塞,不会造成无效的资源占用
  • 耦合度极低,每个服务都可以灵活插拔,可替换
  • 流量削峰:不管发布事件的流量波动多大,都由Broker接收,订阅者可以按照自己的速度去处理事件

缺点

  • 架构复杂了,业务没有明显的流程线,不好管理
  • 需要依赖于Broker的可靠、安全、性能

通过介绍异步通讯,以及优点后,我们大概也就知道为什么使用MQ了,那么现在我们就具体介绍一下,为什么使用消息队列。

2.为什么使用消息队列

使用消息队列的场景会很多,但是主要作用就是以下三点:

  • 解耦
  • 异步
  • 削峰

2.1 解耦

我们还以购物商品为例,支付服务需要发生订单id到订单和物流两个服务,通过使用OpenFegin,进行数据发送,那么现在如果新增了库存服务,也需要支付服务的订单id,或者说订单服务取消了,那么支付服务是不是都要通过不断地修改服务代码进行实现,思考一下如果你是支付服务负责人,你会不会发狂。

深入剖析MQ(消息队列):解耦、削峰、异步_消息队列_03

在购买商品的这个场景中,支付服务和其他服务因为同步调用,存在了严重的系统耦合,支付服务产生一条订单数据,其他相关联的需要订单ID的服务,就需要支付服务发生数据过去,并且此时我们还需要考虑如果和支付服务相关联的服务挂掉,那么我们怎么办?如果高并发情况下会产生什么后果?是不是可能发生所有和支付相关联的服务最终都会挂掉

如果使用 MQ,支付服务产生一条订单数据,发送到 MQ 里面去,哪个系统需要数据自己去 MQ 里面消费。如果新系统需要数据,直接从 MQ 里消费即可;如果某个系统不需要这条数据了,就取消对 MQ 消息的消费即可。这样下来,支付服务压根儿不需要去考虑要给谁发送数据,不需要维护这个代码,也不需要考虑人家是否调用成功、失败超时等情况。

深入剖析MQ(消息队列):解耦、削峰、异步_微服务_04

总结

通过一个 MQ,Pub/Sub 发布订阅消息这么一个模型,支付服务就跟其它系统彻底解耦了

2.2. 异步

还是购买商品场景,不过我们从另外一个角度来分析,支付服务接受支付请求,需要在自己本地写库,还需要在 订单、物流和库存 三个服务写库,自己本地写库要 50ms,订单、物流和库存 三个服务分别写库要 159ms、350ms、450ms。最终请求总延时是 50 + 150 + 350 + 450 = 1000ms,也就是 1s,用户感觉这是什么烂系统,慢的要死。用户通过浏览器发起请求,等待个 1s,这几乎是不可接受的。

深入剖析MQ(消息队列):解耦、削峰、异步_微服务_05

一般互联网类的企业,对于用户直接的操作,一般要求是每个请求都必须在 200 ms 以内完成,对用户几乎是无感知的。

如果使用 MQ,那么支付服务连续发送消息到 MQ 队列中,假如耗时 20ms,支付服务从接受一个请求到返回响应给用户,总时长是 50+ 20 = 70ms,对于用户而言,其实感觉上就是点个按钮,70ms 以后就直接返回了,爽!网站做得真好,真快!

深入剖析MQ(消息队列):解耦、削峰、异步_消息队列_06

2.3. 削峰

在每年的双十一促销活动期间,用户量会急剧增加,导致系统的并发请求压力大幅上升。

  • 首先,当用户下单时,订单服务将订单信息发送到消息队列中,而不是立即处理该订单。这样订单服务快速地返回响应给用户,表示订单已经成功接收。
  • 然后,支付服务作为一个消费者订阅了订单队列,并从队列中接收订单消息。支付服务根据接收到的订单信息进行支付处理,并将支付结果发送到支付结果队列中。
  • 同时,库存服务也作为一个消费者订阅了订单队列,从队列中接收订单消息。库存服务根据接收到的订单信息,检查商品库存情况,如果库存充足,则进行扣减,并将扣减结果发送到库存结果队列中。
  • 最后,物流服务作为一个消费者订阅了库存结果队列,从队列中接收库存扣减结果消息。如果库存扣减成功,则物流服务开始准备发货并将物流跟踪号发送给用户。

深入剖析MQ(消息队列):解耦、削峰、异步_消息队列_07

3.MQ技术实现对比

MQ,中文是消息队列(MessageQueue),字面来看就是存放消息的队列。也就是事件驱动架构中的Broker。

比较常见的MQ实现:

  • ActiveMQ
  • RabbitMQ
  • RocketMQ
  • Kafka

几种常见MQ的对比:


RabbitMQ

ActiveMQ

RocketMQ

Kafka

公司/社区

Rabbit

Apache

阿里

Apache

开发语言

Erlang

Java

Java

Scala&Java

协议支持

AMQP,XMPP,SMTP,STOMP

OpenWire,STOMP,REST,XMPP,AMQP

自定义协议

自定义协议

可用性

高,基于主从架构实现高可用

同 RabbitMQ

非常高,分布式架构

非常高,分布式,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用

单机吞吐量

万级,比 RocketMQ、Kafka 低一个数量级

同 ActiveMQ

10 万级,支撑高吞吐

10 万级,高吞吐,一般配合大数据类的系统来进行实时数据计算、日志采集等场景

消息延迟

微秒级

毫秒级

毫秒级

毫秒以内

消息可靠性

高(基本不丢)

一般(有较低的概率丢失数据)

高(经过参数优化配置,可以做到 0 丢失)

一般(同 RocketMQ)

  • 追求可用性:Kafka、 RocketMQ 、RabbitMQ
  • 追求可靠性:RabbitMQ、RocketMQ
  • 追求吞吐能力:RocketMQ、Kafka
  • 追求消息低延迟:RabbitMQ、Kafka

总结:中小型公司,技术实力较为一般,技术挑战不是特别高,用 RabbitMQ 是不错的选择;大型公司,基础架构研发实力较强,用 RocketMQ 是很好的选择。

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

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月13日 0

暂无评论

推荐阅读
  gBkHYLY8jvYd   2023年12月09日   30   0   0 cii++数据
2HyDHh3MOg71