先来看看没有使用消息队列微服务之间调用的场景
在订单系统里面,描述的是一个大致的流程,上面是没有消息队列介入订单系统的样子。
对于用户来说,下订单这个这个动作完成之后,需要看到的是下单成功这样一个提醒。再之后是支付这个步骤。用户是不需要知道在下完单之后,整个后台发生了哪些动作。
对于用户来说只需要看到下单成功这个提醒就ok了。下单成功后台会发生这几个步骤。创建订单,扣减库存,加积分,派发优惠券。这里只是列举了部分,其实还有很多服务被调用。
在微服务里面,上面创建订单,扣减库存等会被拆分为独立的服务来做,肯定不是在单体的项目里面,不会作为一个项目而存在,而是每一个部分会作为独立的项目而存在。换句话说这些项目会部署在不同的服务器上面。这就涉及到不同的服务的调用。
对于下订单这个服务来说,需要调用很多的服务来完成他的这个业务。那么这个调用是同步进行的还是异步进行的?
上面图是同步的通信,就是没有使用消息队列的通信方式。当用户下完订单之后,它会去调用创建订单这个动作,这个动作执行完之后会去调用另外一个服务扣减库存。注意这里每个服务调用完之后才会去调用另外一个服务。
也就是说下订单到下单成功,需要将创建订单,扣减库存,加积分,派发优惠券这几个服务执行完才会提示用户下单成功。
用户在下单再到下单成功,那么对用户来说必须得等待这几个服务的逐一完成,最后才能看到下单成功这个提示。
创建订单需要执行300毫秒的时间,扣减库存.......以此类推。当用户下单再到看到下单成功,这个需要经过这些服务调用累加的过程。这个时间是比较长的。
这里也涉及到网络通信,因为网络是不可靠的,如果网络抖动非常严重,就可能让这次调用的时间变的非常长。更严重的是网络抖动导致服务根本调用不到,那么在整个服务的调用链上面,是有很多服务需要调用,不敢保证每个服务都是快速调用的。所以用户下单这件事情就变的没有那么的容易。
所以同步的通信并不适合在订单系统里面出现,对用户体验感非常差。下单成功需要一段时间,而不是立刻马上。同时想下单成功也变成了概率的事件,下单成功可能只要80%概率。所以这里有两个问题性能不够ok,其次它的成功率也不够高。
使用消息队列能够帮我们解决什么样的问题?
使⽤异步的通信⽅式对模块间的调⽤进⾏解耦,可以快速的提升系统的吞吐量。上游执⾏完消息的发送业务后⽴即获得结果,下游多个服务订阅到消息后各⾃消费。通过消息队列,屏蔽底层的通信协议,使得解藕和并⾏消费得以实现。
用户下单到想看到下单成功这个提醒,它的时间是比较久的,也就是它的接口响应速度是非常慢的。
如何提高响应的时间和提高成功率。比如买个东西还会提示下单失败。
在这中间引入了一个中间者消息队列。先不看消息队列的工作逻辑,先来看看效果。
完成下订单这个动作会往消息队列里面发送一条消息。这个消息可以理解为消息队列里面一条传递信息的个体。这个消息进来之后,不管什么逻辑,这个下订单这个动作可以马上返回一个结果,就是下单成功了。它能够得到一个马上下单成功的提醒。
这一下就可以解决两个问题,一个问题是它的速度非常的快,不需要等待所有的业务执行完才返回而是只发一条消息到消息队列马上就能够得到一个结论下单成功。
对于业务的上游来说,一下子就将两个问题解决了。第一个就是响应的时间,只需要一个发送消息的时间。其次不存在失败的问题,除非消息队列本身出现了问题。但是在消息队列本身会去做高可用。所以几乎不会存在下单失败这个问题。
下单成功对于用户来说很简单,然后去做支付动作。但是对于业务本身来说依然需要去创建订单,扣减库存,加积分,优惠券。它怎么做这些事情,当然需要去订阅这样一个队列。
下单紫色的圈就是这个消息,消息体里面包含了很多信息,每个业务订阅者这个队列他们都能够得到这个消息。得到这个消息就可以去做自己的事情了,比如创建订单,扣减库存等等.......在执行业务的时候数据都在消息里面。业务逻辑需要的数据都在这个消息里面可以拿到。
在此期间各个业务模块相互不影响,因为每个微服务几乎同时得到这个消息对象的。它们几乎就可以同时的工作。对于下游来说,可以顺利的得到消息对象,并且可以顺利的完成他的业务,这样就ok了。
总结
在未出现消息队列的时候,这些服务的调用是同步的过程,当出现了消息队列之后会发现已经变成了异步的过程。
异步的过程在于提高整个系统的吞吐量。只要消息发送到队列,那么就得到应该Ok的指示。对于上游来说就可以很快的结束业务。
对于下游来说,既然已经在消息队列里面了,那么下游可能就不那么追求实时性。不是要立刻执行完才算下单成功,下游拿到这些消息了可以慢慢的,不追求实时的消费,但是可以将消息逐一的进行处理。
允许异步的不实时的场景出现。可能在用户进行支付的时候,这些东西都已经创建好了。