业务背景
重构项目,在测试环境联调,发布到一台服务器上启动。在app上触发一条消息到mq topic A,然后我这边消费消息,将消息通过微信推送给用户。
问题描述
触发消息后,结果却在1s内收到了两次微信通知,并且回执和库中却都收到了两条记录。
但是在服务器上面查找日志时只收到了其中的一次请求。
原因分析
触发了一条,却发了两条。百思不得其解?
于是就想到了其中一个方案,停了服务器上的服务后,再次触发,发现还会触发微信消息。那就说明有一台服务在跑。怎么找到这台服务?
想到mq监控台页面可以看到是哪些ip在连接。然后就通过对应的topic和消费者,直接查找到连接的实例ip。
果不其然,有个同事在20多分钟前本地启动了重构前的服务。而测试环境和本地的mq连接并没有隔离,并且重构前后的topic和消费者是一样的。
所以mq又被另一台消费了一次。
但是同一个topic和消费者,为什么会被消费两次呢?
RocketMQ提供了ack机制,以保证消息能够被正常消费。发送者为了保证消息肯定消费成功,只有使用方明确表示消费成功,RocketMQ才会认为消息消费成功。中途断电,抛出异常等都不会认为成功——即都会重新投递。
经过分析发现:
这条消息先是被本地的服务给消费到了,但是本地的网络和服务器是比较卡的。
相当于网络是不稳定的,那么mq就没有收到成功的返回,那它就会重新发送到另外一台服务上了。
消息会被重复消费,那对客户的体验是很不好的。所以,幂等性校验还是很有必要的。
解决办法
RocketMQ不解决消息重复推送问题。所以需要自己处理。
-
每次消费数据,将唯一标识放入redis,key为唯一标识,value为incr自增。
过期时间设置在60s。
然后消费时看redi

本文讲述了在重构项目中遇到的消息重复消费问题,分析了由于网络抖动导致MQ消息被同一topic和消费者消费两次的情况。提出了通过Redis实现幂等性校验的解决方案,以避免对用户体验的影响。同时强调了检查服务连接情况和幂等性设计的重要性。
最低0.47元/天 解锁文章
680

被折叠的 条评论
为什么被折叠?



