目录
1、引入
2、同步调用
2.1、例子:支付功能
2.2、同步调用的好处
2.3、同步调用的缺点
3、异步调用
3.1、异步调用的方式
3.2、异步调用的优势
3.3、异步调用的缺点
3.4、什么场景下使用异步调用
3.5、MQ技术选型
1、引入
为什么想要异步通信呢?
举个例子,我们在写项目时,可能就会涉及到要有一个登录功能,而登录功能很可能就会涉及到好几个微服务,如下:
上面图的意思就是在我们进行登录时,先要验证用户信息,成功后,还要调用到风控微服务来检查登录风险,如果说登录是存在风险的,就要继续调用短信微服务来告知用户,这一套流程下来,登录功能才算结束,其实是一个比较耗时的过程。
为了解决上述问题,就引入了异步通信,如下图:
上面图的意思就是在登录微服务中,验证了用户信息之后,会直接给mq中存一个消息,消息成功存放后,他这边的登录功能就会直接结束了,而mq收到这个消息后,就会把这个消息广播出来,其他的微服务区监听这个广播就可以了,这样一来就是并行执行了,大大提升了效率~
注!!!并不是说都要用异步调用,有的操作是必须使用同步调用的,换句话说有的操作使用异步调用没必要~
2、同步调用
2.1、例子:支付功能
下图是一个支付功能的所有功能点及需要使用到的各个服务:
上图分析:流程 - 进行支付操作时,我们先去扣除用户余额,扣除失败,可能是余额不足,支付操作结束; 扣除成功,则进行第二步更新支付状态,然后再去更新订单状态~ 到这一步,我们其实支付操作就结束了,但后续产品经理需要我们去增加功能,一个是支付成功后,短信提醒用户,给用户累加积分等~
2.2、同步调用的好处
- 时效性强,等待到结果后才返回
- 根据上面的例子理解:我们进行支付操作时,第一步扣除余额,余额扣除成功后,我们进行后续的更新支付状态、更新订单状态等才会有意思,不然如果我们使用异步,把后续的支付状态、订单状态都更新了,突然发现扣除余额失败了,我们再去回滚,这是不是有点没必要了~ 因此我们在扣除余额状态成功后再去进行后续操作,这是前因后果的依赖性比较强的,换句话说就是时效性强,等到结果后才返回~
2.3、同步调用的缺点
- 拓展性差
- 根据上面的例子理解:上述例子我们提到,后面的两个通知服务和积分服务很可能是后续产品新加的需求,那我们想要加这个功能,就需要在支付服务上去改代码区调用到这两个新服务,就会很麻烦~
- 性能下降
- 根据上面的例子理解:上述一个支付服务下就要调用4个服务,还都是同步调用,4个服务5个步骤,一个步骤花费50ms,那一个支付服务就需要花费300ms,性能确实是,太差了,用户在前端点一下,要卡半天采用反应,体验感也不好~
- 级联失败问题
- 根据上面的例子理解:如果说支付服务下的某个服务出现了故障,这个故障没有及时解决,就可能会导致支付服务的资源耗尽,支付服务也故障了,就造成了级联失败
3、异步调用
3.1、异步调用的方式
异步调用的方式就是基于消息通知的方式,一般包含三个角色:
- 消息发送者:投递消息的人,就是原来的调用方
- 消息代理:管理、暂存、转发消息,你可以把它理解成微信服务器
- 消息接受者:接收和处理消息的人,就是原来的服务提供方
如下图:
根据上图理解异步调用: 例如正在跨年夜,我们要给跟多人发送新年快乐的消息,同步调用我们可以为,我们自己需要给一个人发送完新年快乐之后,他也给我们回复了同乐,然后我们再给第二个人发送新年快乐~ 异步调用我们可以理解为,我们使用微信的群发功能,我们把消息发出来,微信服务器作为一个消息代理,收到这个消息后,把这个消息广播出来,而我们的微信好友就会去监听这个广播,就会收到你的新年祝福了~
类比到上面提到的支付的这个例子,调用链就变成了如下操作:
上述的支付服务就不用再同步调用业务关联度低的服务了,而是发送消息通知到Broker(消息代理)
3.2、异步调用的优势
- 耦合度低,拓展性强
- 在上面提到的,短信通知服务和积分服务可能是产品后续新加的功能,我们只需要在短信服务和积分服务加一个监听,监听支付服务就可以了,就不需要修改原本的支付服务的代码了,耦合度大大降低~
- 异步调用,无需等待,性能提高
- 在上面提到,使用同步调用时,一个支付服务可能就需要花费300ms,但在异步调用后,只有前两个步骤(扣除余额,更改支付状态)需要使用同步调用等待结果,后面支付服务发一个广播后,这个支付服务就结束了,时间花费基本在100+ms左右,性能提高~
- 故障隔离,下游服务故障不影响上游业务
- 后面的三个服务(交易服务、通知服务、积分服务)监听到广播后执行就可以了,即使出现了故障和上游的支付服务也没有关系,支付服务是感知不到的~
- 缓存消息,流量削峰填谷
- 支付服务在收到大量的请求时,他把前两个步骤处理完就把消息发给代理了,后面的3个服务就不存在说处理不完的情况了,他们3个慢慢处理,处理完一个任务后,再去消息代理那里取新的任务就可以了~ (类似于阻塞队列)
3.3、异步调用的缺点
- 不能立即得到调用结果,时效性差
- 因为上游服务是通知下游服务的, 下游服务什么时候执行,执行有没有成功你都是不知道~
- 不确定下游业务执行是否成功
- 业务安全依赖于Broker(消息代理)的可靠性
- 因为下游的几个服务都是取监听消息代理的,那如果说消息代理挂了,后面的服务都执行不了了
3.4、什么场景下使用异步调用
- 依赖性关系弱(对对方的执行结果不关心 - 对方的执行结果不是特别重要) - 依赖关系弱什么意思:对方的执行结果对你的后续操作没有影响 - 依赖关系若;对方的执行结果对你的后续操作有影响 - 依赖关系强
- 性能要求较高,服务的调用链超长 - 使用异步
3.5、MQ技术选型
MQ(MessageQueue),中文:消息队列, 字面来看就是存放消息的队列,也就是异步调用中的Broker(消息代理)
以下是几种工具,后面我们是学习RabbitMQ~