初识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

相关推荐
spiker_7 小时前
使用 RabbitMQ 和 Go 构建异步订单处理系统
golang·rabbitmq·ruby
晚睡早起₍˄·͈༝·͈˄*₎◞ ̑̑10 小时前
苍穹外卖学习笔记(一)
java·笔记·学习·spring·kafka·tomcat·maven
流烟默11 小时前
Kafka【十三】消费者消费消息的偏移量
分布式·kafka·消费偏移量
程序员小雷12 小时前
字节面试 | 如何测试RocketMQ、RocketMQ?
测试工具·面试·职场和发展·单元测试·测试用例·rocketmq·postman
码码哈哈0.018 小时前
每天一道面试题(5):Kafka 的零拷贝原理
分布式·kafka
Casual_Lei18 小时前
Kafka 常用的传输和序列化数据方式
分布式·kafka
slb19062318 小时前
Kafka 分布式消息系统详细介绍
分布式·kafka·kafka 分布式消息系统
鬼钺魂19 小时前
springboot集成activemq,并配置多个mq
spring boot·activemq·java-activemq
充值内卷1 天前
ASP.NET Core 入门教学八 集成RocketMQ消息队列
后端·asp.net·rocketmq
九品神元师1 天前
Kafka命令
分布式·zookeeper·kafka