初识MQ——学习MQ之前需要了解的知识点

目录

前言

[1. 同步和异步通讯](#1. 同步和异步通讯)

[1.1 同步通讯](#1.1 同步通讯)

[1.2 异步通讯](#1.2 异步通讯)

[2. MQ技术对比](#2. MQ技术对比)


前言

在现在的大数据时代,高并发的情况越来越普遍,系统一个不注意,就可能崩溃无法访问了。这是开发最不想看到的情况,如果是上班还好,可以分析定位。要是下班的时候,那就完了,可能美好的休息时光就没了。最惨的就比如微博奔溃,程序员结婚当天加班了。为了避免这种悲催的情况,就需要用到中间件------MQ。

1. 同步和异步通讯

在学习MQ之前,我们首先要弄清楚,服务之间的通讯情况。微服务间的通讯分为同步通讯和异步通讯两种:

  • 同步通讯:就像打电话,需要实时响应。
  • 异步通讯:就像微信、QQ发消息,不需要马上回复。

这两种方式各有优势,打电话可以立即得到响应,但是你却不能跟多人同时通话。发送微信可以同时跟多人聊天,但是往往响应会有延迟。

1.1 同步通讯

像微服务常用的Feign调用就属于同步方式,虽然调用可以实时得到结果,但是存在一些问题。以下图为例,说明一下:

我们团队开发了一个购物的系统,用户下单之后,支付服务去调用订单服务修改订单状态,修改完成之后返回给支付服务,之后支付服务又去调用了仓储服务去减少库存,然后再返回给支付服务,支付服务就返回给用户表示支付成功。到这里,系统的流程就算走完了。

1)耦合度高

这时候来了一个神奇的物种------产品经理,他看了这个项目之后说,我觉得我们可以给系统升个级,用户支付完了之后,可以给用户来个短信提醒。他这短短几句话说的简单,你是不是要好几天在支付服务里面去改代码,添加一个短信的业务。然后这产品经理继续说,想再加个优惠券功能,你是不是还要继续在支付系统中改代码?要是产品经理每隔十天半个月给你来一次系统升级,这改来改去的谁受的了啊。所以这就是耦合度高带来的很严重的问题。

2)性能下降

我们再来假设一下。除了支付服务外,我们的每个服务业务处理都需要150ms的时间。因为它是同步调用,所以支付服务在调用其他服务的时候需要等待,假设支付服务处理自身业务逻辑的时间是50ms,那么整个系统的耗时加起来是不是就是500ms。这时候如果出现高并发,你的系统能抗住吗?请求一多,系统容易造成阻塞,这时候系统的性能和吞吐量是不是都下降了。

3)浪费资源

而且,支付服务在调用订单服务的时候,是不是都是干等着它的响应结果。CPU占着,内存也占着,但是它什么也没做。等订单服务返回之后,再来调用仓储服务。然后继续干等着。现在才是三个服务,以后变成十个,一百个服务,支付服务会浪费多少资源啊。

4)级联失败

假设,支付服务在访问仓储服务的时候,仓储服务挂了,支付服务还在等着仓储服务的响应结果。它也不会释放资源,后面进来的请求越来越多,等到资源耗尽的时候,服务崩溃。用户不得骂街吗?你这什么垃圾系统,我就访问一下,系统就挂了。

缺点图片如下:

最后总结一下同步通讯的特点:

同步调用的优点:

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

同步调用的问题:

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

1.2 异步通讯

异步调用则可以避免上述问题。异步调用常见实现就是事件驱动模式。那么什么是事件驱动?我们继续以上面的例子来说明一下:

我们不再是支付服务直接调用其他的服务,而是引入了一个新的东西就是Broker(事件代理)。支付服务支付成功之后,直接返回给用户支付成功的信息。并且把支付成功当作一个事件交给Broker来管理。而订单服务、仓储服务、短信服务在Broker订阅事件之后,一旦发生支付成功的事件,Broker就会通知三个服务订单已经支付,三个服务就会继续各自的处理逻辑。这样的好处就是:

1)服务解耦

后续系统升级,想要添加或者去除某些服务的时候,只要修改订阅事件的服务就可以了。大大降低了服务之间的耦合度。

2)性能提升,吞吐量提高

用户从支付开始到支付完成,只会花费支付服务和发布支付成功事件的时间总和,也就是60ms,跟后面的其他服务花费的时间没有任何关系了。跟上面的同步通讯的耗时相比,减少了很多。耗时缩短了,那么我们的性能和吞吐量是不是就提高了。

3)服务没有强依赖,不担心级联失败问题

因为支付服务不再直接调用仓储服务,如果现在仓储服务挂掉了,也跟支付服务没有关系了。服务之间没有了强依赖,自然就不用再担心级联失败的问题了。

4)流量削峰

如果现在来了大量的服务请求,我们的订单服务因为处理的时间缩短,不会造成阻塞,返回给用户表示服务成功。然后把事件都放在了Broker里面,这时候Broker就起到了一个缓冲的作用。就像是洪水来了的时候,有了一个大坝拦住了。剩下的服务能处理几个就先处理几个,这几个处理完了之后,再处理后面的。这样压力都有Broker来抗住,一个高的并发就被砍平了。对我们的系统起到了一个保护的作用。特别是在秒杀,抢票这样一个高并发的场景下。

在事件模式中,支付服务是事件发布者(publisher),订单服务、仓储服务和短信服务都是事件订阅者(Consumer)。 发布者发布事件到Broker,不关心谁来订阅事件。订阅者从Broker订阅事件,不关心谁发来的消息。 Broker是一个像数据总线一样的东西,所有的服务要接受数据和发送数据都发到这个总线上,这个总线就像协议一样,让服务间的通讯变得标准和可控。

现在开源软件或云平台上 Broker 的软件是非常成熟的,比较常见的一种就是我们今天要学习的MQ技术。

总结

异步通讯的优点:

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

异步通讯的缺点:

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

如果你的业务场景比较追求时效性,需要马上得到其他服务的回应,建议你还是选择同步通讯的模式。如果你不太在意时效性,不需要马上得到响应,只是要其他服务去处理某些事件,并且对并发和吞吐量的要求比较高的话,你就可以使用异步通讯了。

2. 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 自定义协议 自定义协议
可用性 一般
单机吞吐量 一般 非常高
消息延迟 微秒级 毫秒级 毫秒级 毫秒以内
消息可靠性 一般 一般

追求高可用性:Kafka、RocketMQ、RabbitMQ

追求可靠性:RabbitMQ、RocketMQ

追求吞吐能力:RocketMQ、Kafka

追求消息低延迟:RabbitMQ、Kafka

相关推荐
慧一居士5 分钟前
Kafka批量消费部分处理成功时的手动提交方案
分布式·后端·kafka
搞不懂语言的程序员31 分钟前
如何实现Kafka的Exactly-Once语义?
分布式·kafka·linq
小名叫咸菜1 小时前
Kafka简介
kafka
zcyf08091 小时前
kafka理论学习汇总
java·分布式·学习·kafka
shepherd1112 小时前
Kafka生产环境实战经验深度总结,让你少走弯路
后端·面试·kafka
希忘auto5 小时前
详解RabbitMQ工作模式之简单模式
rabbitmq
晴天彩虹雨5 小时前
Flink 消费 Kafka 数据流的最佳实践
数据仓库·flink·kafka·linq
希忘auto8 小时前
详解RabbitMQ工作模式之工作队列模式
rabbitmq
刘某的Cloud17 小时前
rabbitmq常用命令
linux·运维·分布式·rabbitmq·系统
星星点点洲18 小时前
【RabbitMQ】保证消息不丢失
rabbitmq