26 生产案例:从RocketMQ全链路分析用户支付后没收到红包的原因

Posted 鮀城小帅

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了26 生产案例:从RocketMQ全链路分析用户支付后没收到红包的原因相关的知识,希望对你有一定的参考价值。

场景:由用户反馈,按照规则在支付之后应该可以拿到一个现金红包的,但是他在支付了一个订单之后,却并没有收到这个现金红包,于是反馈给客服。

问题排查,查找系统中打印的日志。

发现,按理来说,订单系统在完成支付之后,会推送一条消息到RocketMQ里去,然后红包系统会从RocketMQ里接收那条消息去给用户发现金红包。

但是从订单系统和红包系统当天那个时间段的日志来看,只看到了订单系统有推送消息到RocketMQ的日志,但是并没有看到红包系统从RocketMQ中接收消息以及发现金红包的日志。

由此可见,问题可能就出在这儿了,是不是支付订单消息在传输的过程中丢失了?导致现金红包没有派发出去。

2.订单系统推送消息到MQ的过程会丢失消息吗?

答案是有可能会丢失。

原因有多种:

常见的例子,比如订单系统在推送消息到RocketMQ的过程中,是通过网络去进行传输的,但是这个时候恰巧可能网络发生了抖动,也就是网络突然有问题,导致这次网络通信失败了。于是这个消息就没有成功投递给MQ。

例子二:比如MQ确实收到消息了,但是它的网络通信模块的代码出现了异常,可能是他内部的网络通信的bug,导致信息没成功处理。

例子三:或者在写消息到RocketMQ的过程中,刚好遇到了某个Leader Broker自身故障,其他的Follower Broker正在尝试切换为Leader Broker,这个过程也可能会有异常。

3.消息到达MQ了,MQ自己会导致消息丢失吗?

即使我们的订单系统成功的把消息写入了MQ,也不能想当然的认为你写成功了,消息还是有丢失的可能。

os cache内丢失

根据对RocketMQ 底层原理的分析,可以得知,当你的消息写入MQ之后,其实MQ可能仅仅是把这个消息给写入到page cache里,也就是操作系统自己管理的一个缓冲区,这本质就是写入到内存。

在不了原理的情况下,可能以为真的写成功了一个消息,但是此时仅仅进入了 os cache,还没写入磁盘。

这个时候,一旦出现了Broker机器的崩溃,机器宕机的情况发生,那么os cache内存中的数据就没了。

在上述的情况下,碰上机器宕机,内存里的数据必然就会丢失了,机器即使重启了,然后重启broker进程,此时这个数据也没了。

4.消息进入磁盘了,还会丢失吗

会的,即使Broker把消息写入os cache之后,及时的刷入到磁盘文件里,但是也不能保证数据一定不丢失。

磁盘损坏问题

如果你的磁盘出现故障,比如磁盘坏了,那么上面存储的数据还是会丢失。

5.红包系统拿到了消息,就一定不会丢失了吗?

这是消费者端的问题,消费者也存在丢失消息的问题。

这里就涉及到了底层存储结构以及offset概念了。offset代表了一个消息的标识,代表了他的位置。

场景解读

如图,有两个消息,offset分别为1和2。

假设红包系统已经获取到了消息1了,然后消息1此时就在它的内存里,正准备运行代码去派发现金红包,但是,此时还没派发现金红包。

默认情况下,MQ的消费者有可能会自动提交已经消费的offset,那么如果此时你还没处理这个消息派发红包的情况下,MQ的消费者可能直接自动给你提交这个消息1的offset到broker去了,标示为你已经成功处理了这个消息,如下图:

恰巧在这个时候,我们的红包系统突然故障了,红包系统的机器重启了一下,然后此时内存里的消息1必然就丢失了,而且红包也没发出去。

6.总结

以上是生产者、MQ、消费者可能丢失消息的原因分析过程。

以上是关于26 生产案例:从RocketMQ全链路分析用户支付后没收到红包的原因的主要内容,如果未能解决你的问题,请参考以下文章

如何基于RocketMQ设计一套全链路消息不丢失方案?

33 基于RocketMQ设计的全链路消息零丢失方案总结

从源码分析RocketMQ不保证幂等的三个原因

互联网面试必杀:如何保证消息中间件全链路数据100%不丢失

全链路灰度之 RocketMQ 灰度

大厂钟爱的全链路压测有什么意义?四种压测方案详细对比分析