设为首页 加入收藏

TOP

Redis面试题(五)
2023-09-23 15:44:12 】 浏览:219
Tags:Redis
列中,只有 commit 了,才会真正将消息放在消费者能读取到的 topic 队列中)

Q: 为什么要先发送 half 消息?
A: 前面已经解释过了,主要是为了保证服务 A 和 MQ 之间是否能正常通信,如果两者之间都不能正常通信,后面还玩个锤子,直接返回异常就可以了。

Q: 如果 MQ 接收到了 half 消息,但是在返回 success 响应的时候,因为网络原因,导致服务 A 没有接收到 success 响应,这个时候是什么现象?
A: 当服务 A 发送 half 消息后,它会等待 MQ 给自己返回 success 响应,如果没有接收到,那么服务 A 也会直接结束,返回异常,不再执行后续逻辑。不执行后续逻辑,这样服务 A 也就不会提交 commit 消息给 MQ,MQ 长时间没接收到 commit 消息,那么它就会主动回调服务 A 的一个接口,服务 A 通过接口,查询本地数据后,发现这条消息对应的业务并没有正常执行,那么就告诉 MQ,这个 half 消息不能 commit,需要 rollback,MQ 知道后,就将 half 消息进行删除。

Q: 如果服务 A 本地事务执行失败了,怎么办?
A: 服务 A 本地事务执行失败后,先对自己本地事务进行回滚,然后再向 MQ 发送 rollback 操作。

Q: 服务 A 本地事务提交成功或失败后,向 MQ 发送的 commit 或者 rollback 消息,因为网络问题丢失了,又该怎么处理?
A: 和上一个问题一样,MQ 长时间没有接收到 half 消息的 commit 或者 rollback 消息,MQ 会主动回调服务 A 的接口,通过这个接口来判断自己该对这个 half 消息如何处理。

Q: 前面说的全是事务消息的实现流程,这和事务消息如何保证数据的最终一致性有什么关系呢?
A: 有关系。首先,服务 A 执行本地事务并提交和向 MQ 中发送消息这是两个写操作,然后通过 RocketMQ 的事务消息,我们保证了这两个写操作要么都执行成功,要么都执行失败。然后让其他系统,如服务 B 通过消费 MQ 中的消息,然后再去执行自己本地的事务,这样到最后,服务 A 和服务 B 这两个系统的数据状态是不是达到了一致?这就是最终一致性的含义。

而RocketMQ作为一种消息队列,其本身特点是异步、解耦,无法保证服务A和服务B在同一时刻的数据强一致性。它只能保证最终一致性。

目前通过可靠消息来保证数据的最终一致性是很多大厂都采用的方案,基本都是通过 MQ 和补偿机制来保证数据的一致性。(所谓的可靠消息,就是消息不丢失,如何保证 MQ 的消息不丢失,下篇文章会写,这也是面试常考题)

Q: 服务 B 本地事务提交失败了,怎么办?
A: 如果服务 B 本地事务提交失败了,可以进行多次重试,直到成功。如果重试多次后,还是提交失败,例如此时服务 B 对应的 DB 宕机了,这个时候只要服务 B 不向 MQ 提交本次消息的 offset 即可。如果不提交 offset,那么 MQ 会在一定时间后,继续将这条消息推送给服务 B,服务 B 就可以继续执行本地事务并提交了,直到成功。这样,依旧是保证了服务 A 和服务 B 数据的最终一致性。
————————————————
版权声明:本文为CSDN博主「qq_34436819」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_34436819/article/details/114444204

首页 上一页 2 3 4 5 6 7 下一页 尾页 5/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Spring 多线程的事务处理 下一篇主动写入流对@ResponseBody注解的..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目