mq消息落地及业务处理踩坑记录

一.业务场景

消费mq订单消息,落订单中间表,成功后,生成订单跟踪表。

二.生产出现问题

  1. 中间表及订单跟踪表出现大量重复数据,进而又导致,后续流程出错,而且生产上跑了两天才发现问题,存在几万条脏数据。
  2. 新表加唯一索引后,捕获了DuplicateKeyException异常,生产依然出现大量唯一键冲突异常,影响其他错误问题定位。

三.原因

  1. 根本原因:消息重复下发了。且重复次数极多,有点重复下发几十次,且mq key不同。todo 未找到未什么重复下发。
  2. 自身原因:代码及数据库层没有控制好。像这种存在幂等性场景,本该考虑到,外部的消息是否重复下发,无法控制。

四.补救

  1. 新建中间表,加唯一索引:因为中间表和订单跟踪表脏数据太多,而且存在业务联系复杂,需要花时间定位脏数据,运维执行sql,挽救很难了,现在应保证后续数据正确。
  2. 捕获唯一键异常:以为是消费异常,导致一直重试,一直重复下发。想捕获这个异常,也就不会抛异常,重试了。其实不是,因为第一次消费是正常的,且就算重复也是有次数的,不会这么多。而且DuplicateKeyException异常并没有捕获到,断点测试根本就没有进入catch,然后尝试了代码中抛出的其他异常,断点测试可以进入catch,但是最终还是抛出了UnexpectedRollbackException异常,捕获这条路是走不通了,应该是有方法没有找到。
  3. 加redis分布式锁:针对单号加锁,存在一个问题,过期时间该设置多少?最终没有采用这种方案,1.过期时间无法确定,2.过期后再重复下发。3.四个场景都会都对单号加锁,会互相影响。
  4. 先查询处理:存在就不执行;最终采用这种方案。这里多个节点是否存在并发问题,应该不会,就算两个节点都没有查询到数据,进入了后续流程,写入订单跟踪表。先落中间表,再落订单跟踪;或者先落订单跟踪,再落中间表,因为在一个事务里面,只要中间表抛异常,后续流程就不会执行。
  5. 比较查询和用redis选择问题。个人还是觉得redis更好,因为redis比查询数据库快很多,且是分布式锁。而且redis存在问题也可以解决,1.重复也是基于业务,过期时间可以大概确认;2.有唯一主键兜底处理,过期再重复没关系;3.每种场景对key,单号设置前缀,不同的key。

五.启示

  1. 细心,再细心:不要出现低级bug,跟高中考试一样,哎呀,如果把不该错的都做对,分数高很多。高分的人为什么没有错,只能说明基础不牢,技术不照,写代码粗心,做其他事情一样粗心。
  2. 测试:不测试=有bug,无论新的东西,还是改动东西,都必须要测,看着简单,可能就把流程性bug给测试,把bug发到生产。
  3. 日志:把日志打清楚,要能区分开,尤其关键节点,方便问题排查。
  4. 上生产后看日志:1.有没有报错;2.关键日志有没有问题;3.正常流程是不是通的。有些问题,上了才知道,有些场景想不到。早发现,早治疗。
  5. 考虑量:生产上量大的多,要分批,写入更新查询分批进行。
  6. 幂等性:1.重复操作会不会有问题;2.加分布式锁;3.建表加唯一索引;4.乐观锁;5.前置状态。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值