目录
学习MQ之前有必要先去温故下微服务知识体系,以加深本章节的理解
[1. 基本介绍](#1. 基本介绍)
[2. 同步通讯](#2. 同步通讯)
[2.1. 什么是同步通讯](#2.1. 什么是同步通讯)
[2.2. 同步通讯存在的问题](#2.2. 同步通讯存在的问题)
[2.3. 同步调用的优点](#2.3. 同步调用的优点)
[2.4. 知识小结](#2.4. 知识小结)
[3. 异步通讯](#3. 异步通讯)
[3.1. 异步通讯相比较同步通讯](#3.1. 异步通讯相比较同步通讯)
[3.2. 异步通讯的好处](#3.2. 异步通讯的好处)
[3.3. 异步通讯的缺点](#3.3. 异步通讯的缺点)
[4. 两种通讯方式的简单对比](#4. 两种通讯方式的简单对比)
[1. 什么是MQ](#1. 什么是MQ)
[2. 为什么要用MQ【业务场景】](#2. 为什么要用MQ【业务场景】)
[2.1. 异步](#2.1. 异步)
[2.2. 应用解耦](#2.2. 应用解耦)
[2.3. 流量削峰](#2.3. 流量削峰)
[3. 企业常用MQ产品](#3. 企业常用MQ产品)
[4. MQ 的选择](#4. MQ 的选择)
学习MQ之前有必要先去温故下微服务知识体系,以加深本章节的理解
接下来,让W哥带你先去梳理下微服务间的通讯方式吧!
一、微服务间的通讯方式
1. 基本介绍
我们知道微服务之间的通讯方式有同步和异步两种方式:
- 同步通讯:就像打电话,需要实时响应。
- 异步通讯:就像发邮件,不需要马上回复。
这两种通讯方式各有优劣,比如:打电话可以立即得到响应,但是你却不能跟多个人同时通话。
- 因为打电话,一般是有重要事情,当时就要说明白,需要立即得到回复!
发送邮件可以同时与多个人收发邮件,但是往往响应会有延迟。
- 因为邮件发出的消息永远保留在那,什么时候回复消息,不知所然!而且现实生活中,我们也明白我们只能
跟一个人打电话,不可能出现一个手机号码,跟多人人打电话,发消息确实可以发送许多人,
就比如:
- QQ 发消息、微信发消息都能实现一个人跟多人聊天,打 QQ 电话、微信电话却一次只能跟一个人打电话,
- QQ 发消息、微信发消息就是同步通讯,QQ 电话和微信电话就是典型的同步通讯,
所以同步通讯就像打电话,需要实时响应,异步通讯就像发邮件,不需要马上回复。
2. 同步通讯
2.1. 什么是同步通讯
我们之前学习的Feign调用就属于同步方式,虽然调用可以实时得到结果,但存在下面的问题:
现在我就拿下图作为例子进行解析问题所在:
首先这张图是微服务开发,我们知道微服务开发就是为了降低耦合度,每一个微服务都是一个独立的项目,专门
负责自己那一块业务,然后服务消费者远程调用服务提供者,就如前面所操作的用户微服务和订单微服务分别是
服务提供者和服务消费者做为案例!
再来看这张图,这张图就是用户进行刷卡支付,因为是进行微服务开发,每个模块只负责自己那一块业务,于是
我们就可以将其拆分为多个微服务进行开发,即支付服务只负责支付功能、订单服务负责订单功能、仓储服务服
务存储信息功能、短信服务负责发送和接收短信功能等等,但是现在存在一个问题,因为是服务消费者远程调用
服务提供者,如果服务提供者出问题,那么服务消费者固然也出问题,因为这是一个远程调用过程,于是总结出
如下四个同步通讯的问题!
2.2. 同步通讯存在的问题
问题一:耦合度高
每次加入新的需求,都要修改原来的代码!
比如:
支付服务新增需求,那么就需要添加代码,但是支付服务要远程调用订单服务、仓储服务、短信等服务等,那这
些服务肯定也需要做出改变,因为支付服务需求改变,肯定也会涉及它所调用服务,所以耦合度比较高,就前面
所学可知,远程调用 Feign 的客户端与服务提供者的 controller 代码非常相似,因此更加确认,会导致耦合度
高,代码都要进行修改!
问题二:性能和吞吐能力下降
调用者需要等待服务提供者响应,如果调用链过长则响应时间等于每次调用的时间之和
解析:
一个微服务既可以是服务提供者,又可以是服务消费者,那么上层微服务调用中层微服务,中层微服务调用下层
微服务,那么响应时间相比就比较长,
比如:
上层微服务需要等待中层微服务调用返回结果,中层微服务需要等待下层微服务调用返回结果,等等
(就是一个递归调用过程)
因此叠加起来非常耗时间,导致性能和吞吐能力下降,简单来说就是响应慢了!
问题三:有额外的资源消耗
调用链中的每个服务在等待响应过程中们不能释放请求占用的资源,高并发场景下会极度浪费系统资源
解析:
上层微服务需要等待中层微服务调用返回结果,中层微服务需要等待下层微服务调用返回结果,等等
(就是一个递归调用过程)
比如:
现在我在下层微服务,上层微服务和中层微服务所占用系统资源都在等待下层微服务处理的结果,因此不可能释
放自己这个请求所占用的系统资源,微服务等待下层微服务处理请求发送过来的数据,发送过来的数据进行业务
逻辑处理后,返回结果数据给中层微服务,中层微服务将下层微服务业务逻辑处理的数据再次进行业务逻辑处
理,业务逻辑处理完后的数据返回给上层微服务,上层微服务再次将中层微服务处理后的返回结果数据进行业务
逻辑处理,业务逻辑处理完毕后,再将数据交给客户端浏览器,然后再由前端工程师拿着数据进行处理,重新渲
染页面!
细节问题:开发的核心就是数据处理,所以数据一定要在开发前进行确定好,一般都要通过需求分析、场景调
研,然后实施,
比如:
数据库人员设计好数据、前端人员设计好页面、后端人员数据进行业务逻辑处理,
这儿可以连贯下三层架构思想和前后端交互思想,因为话语太多,本人就暂时未做详细连贯,简单连贯!
客户端发送 Ajax 请求给服务器 -> 服务器收到请求 -> 控制器 -> 业务逻辑层 -> 持久化层 -> 访问数据库 -> 操
作表 -> 数据封装入数据模型(即实体类) -> 数据响应格式 -> 视图层
问题四:有级联失败问题
如果服务提供者出现问题,所有调用者都会跟着出问题,这样会导致整个微服务群故
2.3. 同步调用的优点
时效性较强,可以立即得到结果,比如:打电话这个例子
2.4. 知识小结
同步调用的优点:
- 时效性较强,可以立即得到结果
同步调用的问题:
- 耦合度高
- 性能和吞吐能力下降
- 有额外的资源消耗
- 有级联失败问题
3. 异步通讯
3.1. 异步通讯相比较同步通讯
异步调用 / 异步通讯则可以避免同步调用 / 同步通讯 存在的问题:
我们以购买商品为例:用户支付后需要调用订单服务完成订单状态修改,调用物流服务,从仓库分配响应的库存
并准备发货。
在事件模式中,支付服务是事件发布者(publisher),在支付完成后只需要发布一个支付成功的事件
(event),事件中带上订单id,订单服务和物流服务是事件订阅者(Consumer),订阅支付成功的事件,监听
到事件后完成自己业务即可。
图解可知,支付服务是之前所学习的服务消费者,订单服务和物流服务是之前学习的服务提供者,之前用的是微
服务 Fegin 远程调用同步通讯方式,现在用的是 MQ 消息队列异步通讯方式
为了解除事件发布者与订阅者之间的耦合,两者并不是直接通信,而是有一个中间人(Broker),发布者发布事
件到 Broker,不关心谁来订阅事件,订阅者从 Broker 订阅事件,不关心谁发来的消息。
Broker 是一个像数据总线一样的东西,所有的服务要接收数据和发送数据都发到这个总线上,这个总线就像协议
一样,让服务间的通讯变得标准和可控。
3.2. 异步通讯的好处
好处一:吞吐量提升
无需等待订阅者处理完成,响应更快速.
吞吐量是指对网络、设备、端口、虚电路或其他设施,单位时间内成功地传送数据的数量
比如:若是以前同步通讯 Feign 远程调用,服务消费者必须等待服务提供者全部递归处理完成之后才能响应数
据,吞吐量极低!而我们的异步通讯处理数据的能力增强,就是不需要等待订阅者处理完成,
好处二:故障隔离
服务没有直接调用,不存在级联失败问题。
比如:若是以前同步通讯 Feign 远程调用,服务提供者出错,服务消费者也会相应出错,递归调用直接进入炼
狱,全部报错,出故障!
而我们的异步通讯则不会出故障问题:因为服务之间没有直接调用,不存在级联问题。
好处三:调用间没有阻塞
不会造成无效的资源占用
比如:若是以前同步通讯 Feign 远程调用,就会出现耦合问题,就会导致相应的阻塞问题
而我们的异步通讯则不会,原因如下:发布者发布事件到 Broker,不关心谁来订阅事件,订阅者从 Broker 订阅
事件,不关心谁发来的消息。因此不会出现无效资源占用问题。
好处四:耦合度极低,每个服务都可以灵活插拔,可替换
每个服务都可以灵活插拔,可替换
比如:若是以前同步通讯 Feign 远程调用,耦合高,订单服务代码修改,其它服务提供者也应代码修改,而我们
的异步通讯则不会,原因如下:发布者发布事件到Broker,不关心谁来订阅事件,订阅者从 Broker 订阅事件,不
关心谁发来的消息。
好处五:流量削峰
不管发布事件的流量波动多大,都 Broker 接收,订阅者可以按照自己的速度去处理事件
比如:若是以前同步通讯 Feign 远程调用方式,并发量大的情况下,可能会导致超时,因为服务提供者来不及处
理,虽然,我们可以通过微服务保护技术,给我们减少流量,缓慢处理,但这做,也是有点局限,现在可以借助
异步实现技术,让我们的系统变得更高可用。
而我们的异步通讯则 不管发布事件的流量波动多大,都由 Broker 接收,订阅者可以按照自己的速度去处理事件
好在现在开源软件或云平台上 Broker 的软件是非常成熟的,比较常见的一种就是我现在所总结的一种 MQ 技
术!
3.3. 异步通讯的缺点
- 架构复杂了,业务没有明显的流程线,不好管理
- 需要依赖于 Broker 的可靠、安全、性能
不过,好在现在开源软件或云平台上 Broker 的软件是非常成熟的,比较常见的一种就是MQ技术,这就解决了我
们异步通讯的缺点。
4. 两种通讯方式的简单对比
同步通讯经常说服务提供者和消费者
异步通讯经常说消息发布者和消息订阅者
同步通讯的例子:
一个人打电话,一个人与另外一个人通话,还能再跟第二个人通话?
异步通讯例子:
一个人发消息可以给多个人发送消息,不管你有没有接收,反正已经发送出去,不管接受者是谁
好了,现在我们已经对同步和异步的知识有了一定理解
那么接下来,我们就可以来学习下MQ(消息队列)
二、MQ
1. 什么是MQ
MQ(message queue),从字面意思上看,本质是个队列,FIFO 先入先出,只不过队 列中存放的内容是
message 而已,还是一种跨进程的通信机制,用于上下游传递消息。 在互联网架构中,MQ 是一种非常常见的上
下游"逻辑解耦+物理解耦"的消息通信服 务。使用了 MQ 之后,消息发送上游只需要依赖 MQ,不用依赖其他
服务。
2. 为什么要用MQ【业务场景】
2.1. 异步
如: 用户注册发送,注册邮件、注册短信
传统做法 :
(1)、串行 (先发送邮件、再发短信)。问题:持续时间长
(2)、并行(将注册信息写入数据库后,同时发送邮件、短信),速度快、但不能满足高 吞吐需求
消息队列做法 :
将数据写入数据库、同时发送消息给发送邮件和注册,异步处理
2.2. 应用解耦
如:双十一购物节,用户下单后、订单系统通知库存系统。
传统做法 :
订单系统调用库存系统接口。问题:库存接口故障,订单就会失败,而损失大量订单
消息队列做法
订单系统:下单,订单系统完成持久化,将消息写入队列,返回下单成功给用户 库存系统:订阅下单的消息,获
取下单消息,进行库操作,就算库存系统故障,消息队 列也能保证消息可靠投递,不会导致消息丢失。
2.3. 流量削峰
如:秒杀活动、一般会因为流量过大,导致应用挂掉,一般在应用前端加入消息队列。 作用: 1、可以控制活动
人数,超过一定阈值,订单直接丢弃 2、可以缓解短时间的高流量压垮应用(应用程序按自己的最大处理能力获取
订单)
3. 企业常用MQ产品
(1)ActiveMQ
优点:单机吞吐量万级,时效性 ms 级,可用性高,基于主从架构实现高可用性, 消息可靠性较高,概率丢失数
据低
缺点: 官方社区现在对 ActiveMQ 5.x 维护越来越少,高吞吐量场景较少使用。
(2)Kafka
大数据的杀手锏,谈到大数据领域内的消息传输,则绕不开 Kafka,这款为大数据 而生的消息中间件, 以其百万
级 TPS 的吞吐量名声大噪,迅速成为大数据领域的宠 儿,在数据采集、传输、存储的过程中发挥着举足轻重的作
用。目前已经被 LinkedIn, Uber, Twitter, Netflix 等大公司所采纳。
优点: 性能卓越,单机写入 TPS 约在百万条/秒,最大的优点,就是吞吐量高。时 效性 ms 级可用性非常高,
kafka 是分布式的,一个数据多个副本,少数机器宕机,不 会丢失数据,不会导致不可用,消费者采用 Pull 方式获
取消息, 消息有序, 通过控制能够 保证所有消息被消费且仅被消费一次; 有优秀的第三方Kafka Web 管理界面
KafkaManager;在日志领域比较成熟,被多家公司和多个开源项目使用;功能支持: 功能较 为简单,主要支持
简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使 用
缺点:Kafka 单机超过 64 个队列/分区,Load 会发生明显的飙高现象,队列越多, load 越高,发送消息响应时
间变长,使用短轮询方式,实时性取决于轮询间隔时间,消 费失败不支持重试;支持消息顺序, 但是一台代理宕
机后,就会产生消息乱序,社区更 新较慢;
(3)RocketMQ
RocketMQ 出自阿里巴巴的开源产品,用 Java 语言实现,在设计时参考了 Kafka, 并做出了自己的一些改进。
被阿里巴巴广泛应用在订单,交易,充值,流计算,消息推 送,日志流式处理,binglog 分发等场景。
优点: 单机吞吐量十万级, 可用性非常高,分布式架构, 消息可以做到 0 丢失, MQ 功能较为完善,还是分布式的,
扩展性好, 支持 10 亿级别的消息堆积,不会因为堆积导 致性能下降, 源码是 java 我们可以自己阅读源码,定制自
己公司的 MQ
缺点:支持的客户端语言不多,目前是 java 及 c++,其中 c++不成熟;社区活跃度 一般,没有在MQ核心中去实
现 JMS 等接口,有些系统要迁移需要修改大量代码
(4)RabbitMQ
2007 年发布,是一个在AMQP(高级消息队列协议)基础上完成的,可复用的企业消息 系统,是当前最主流的消息
中间件之一。
优点: 由于 erlang 语言的高并发特性,性能较好;吞吐量到万级,MQ 功能比较完 备,健壮、稳定、易用、跨平
台、支持多种语言 如:Python、Ruby、.NET、Java、 JMS、C、PHP、ActionScript、XMPP、STOMP 等,支
持 AJAX 文档齐全;开源提供 的管理界面非常棒,用起来很好用,社区活跃度高;
更新频率相当高 https://www.rabbitmq.com/news.html
缺点:商业版需要收费,学习成本较高
4. MQ 的选择
(1)ActiveMQ
目前,企业已经很少使用ActiveMQ作为消息中间件,这个暂且就不讨论了,感兴趣的同学们,可以去了解了解!
(2)Kafka
主要特点是基于Pull 的模式来处理消息消费,追求高吞吐量,一开始的目的 就是用于日志收集和传输,适合产生
大量数据的互联网服务的数据收集业务。大型公司 建议可以选用,如果有日志采集功能, 肯定是首选 kafka 了。
(3)RocketMQ
天生为金融互联网领域而生,对于可靠性要求很高的场景,尤其是电商里面的订单扣 款,以及业务削峰,在大量
交易涌入时,后端可能无法及时处理的情况。RoketMQ 在 稳定性上可能更值得信赖,这些业务场景在阿里双 11
已经经历了多次考验,如果你的 业务有上述并发场景,建议可以选择 RocketMQ。
(4)RabbitMQ
结合 erlang 语言本身的并发优势,性能好时效性微秒级,社区活跃度也比较高,管理界面用起来十分方便,如果
你的数据量没有那么大,中小型公司优先选择功能比较完 备RabbitMQ。