MQ解决什么问题?
要了解MQ的必要性,需要先了解一下微服务的产生与出现的问题。只有了解了问题产生的原因才能明白MQ的作用。
举个栗子:支付业务
单服务
传统的服务以单服务为主,所有的操作由一个服务器中的一个服务提供,如下图,支付、修改订单状态、创建物流订单。
三个步骤可以放在一个jdbc事务中。一旦哪个步骤出错,其它两个步骤都会放弃。
以防止出现:支付完了,没有订单。订单状态已经更改,没有产生物流订单。要么都成功,要么都失败。以保证业务的正确性。
微服务
在微服务的环境下,会将三个步骤拆分成三个服务,例如:支付服务,订单服务,物流服务。三者顾名思义只做好自己的一件事情。
情况会变复杂,同样以支付业务为例,三个步骤需要有服务间的调用,如下图,有两次调用产生,服务间调用一般有两种方式:restful 的http与RPC。这里不讨论两者的区别。
微服务化的好处:化整为零,单一服务制作单一的事情,可以防止单服务无线膨胀。无论从开发,测试,运维方面单个服务都是占优势的。
微服务带来的问题:
- 分布式事务
服务间调用难以保持一致性。例如上图中的两次调用。因为三个步骤操作的不是同一个数据库,导致无法使用jdbc事务管理以达到一致性。而且两次服务调用,因为涉及到复杂的网络环境,很容易出现,服务调用失败。所以,微服务化之后出现的一个很严重的问题就是,分布式事务问题如何解决。
分布式事务?
分布式事务有几种解决方案,这里仅讨论MQ如何解决分布式事务。
- 两阶段提交
- 补偿事务
- 本地消息表
- MQ 事务消息
MQ作为解决分布式事务的一种,是如何解决分布式事务问题的,如下图,支付服务完成支付步骤后,往MQ发送一条已支付消息,订单服务收到消息后更改订单状态。
有人就想说,这没什么区别么,甚至加了一层MQ,导致需要两次调用,更复杂风险更大?
MQ解决分布式事务是这样做的,A服务保证消息发送成功,MQ保证消息不会丢失,B服务保证消息消费成功。会出现以下情况:
- A服务生产消息失败,回滚支付操作,业务回到最初状态,保证了一致性。
- A服务生产消息成功,完成支付操作,MQ宕机,MQ重启后,消息还存在,订单服务消费消息,完成修改订单操作。保证了一致性。
- A服务生产消息成功,MQ良好,订单服务消费消息失败。但是消息还存在,等订单服务重启后继续消费消息,保证了一致性。
以上就是分布式事务中的最终一致性:即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。
MQ作为完成最终一致性的一种工具。RocketMQ也有自己的事务消息更简单的解决以上问题。