Pulsar 也会重复消费?
许久没有分享 Java 相关的问题排查了,最近帮同事一起排查了一个问题:
排查在使用 Pulsar消费时,发生了同一条消息反复消费的情况。
当他告诉我这个现象的时候我就持怀疑态度,根据之前使用的经验 Pulsar 在官方文档以及 API 中都解释过:
只有当设置了消费的 ackTimeout并超时消费时才会重复投递消息,默认情况下是关闭的,查看代码也确实没有开启。
那会不会是调用了 negativeAcknowledge()方法呢(调用该方法也会触发重新投递),因为我们使了一个第三方库 https://github.com/majusko/pulsar-java-spring-boot-starter 只有当抛出异常时才会调用该方法。
查阅代码之后也没有地方抛出异常,甚至整个过程中都没看到异常产生;这就有点诡异了。
复现为了捋清楚整个事情的来龙去脉,详细了解了他的使用流程;
其实也就是业务出现了 bug,他在消息消费时 debug然后进行单步调试,当走完一次调试后,没多久马上又收到了同样的消息。
但奇怪的是也不是每次 debug后都能重复消费,我们都说如果一个 bug能 100% 完全复现,那基本上就解决一大半了。
所以我们排查的第一步就是完全复现这个问题。
为了排除掉是 IDEA 的问题(虽然极大概率不太可能)既然是 debug的时候产生的问题,那其实转换到代码也就是 sleep嘛,所以我们打算在消费逻辑里直接 sleep一段时间看能否复现。
经过测试,sleep几秒到几十秒都无法复现,最后索性 sleep一分钟,神奇的事情发生了,每次都成功复现!
既然能成功复现那就好说了,因为我自己的业务代码也有使用到 Pulsar的地方,为了方便调试就准备在自己的项目里再复现一次。
结果诡异的事情再次发生,我这里又不能复现了。
虽然这才是符合预期的,但这就没法调了呀。
本着相信现代科学的前提,我们俩唯一的区别就是项目不一样了,为此我对比了两边的代码。
@PulsarConsumer(topic=xx,clazz=Xx.class,subscriptionType=SubscriptionType.Shared)publicvoidconsume(Datamsg){log.info("consumemsg:{}",msg.getOrderId());Locklock=redisLockRegistry.obtain(msg.getOrderId());if(lock.tryLock()){try{orderService.do(msg.getOrderId());}catch(Exceptione){log.error("consumermsg:{}err:",msg.toString(),e);}finally{lock.unlock();}}}
结果不出所料,同事那边的代码加了锁;一个基于 Redis 的分布式锁,这时我一拍大腿不会是解锁的时候超时了导致抛了异常吧。
为了验证这个问题,在能复现的基础上我在框架的 Pulsar消费处打了断点:果然破案了,异常提示已经非常清楚了:加锁已经过了超时时间。
进入异常后直接 negative消息,同时异常也被吃掉了,所以之前没有发现。
查阅了 RedisLockRegistry的源码,默认超时时间正好是一分钟,所以之前我们 sleep几十秒也无法复现这个问题。
总结事后我向同事了解了下为啥这里要加锁,因为我看下来完全没有加锁的必要;结果他是因为从别人那里复制的代码才加上的,压根没想那么多。
所以这事也能得出一些教训:
ctrl C/V 虽然方便,但也得充分考虑自己的业务场景。使用一些第三方 API 时,需要充分了解其作用、参数。你的点赞与分享是对我最大的支持
5分钟学会 gRPC
Java8 之后对新开发者非常友好的特性盘点
简单的 for 循环也会踩的坑
用 Go 实现一个 LRU cache
撸了一个可调试 gRPC 的 GUI 客户端
相关阅读
-
世界热推荐:今晚7:00直播丨下一个突破...
今晚19:00,Cocos视频号直播马上点击【预约】啦↓↓↓在运营了三年... -
NFT周刊|Magic Eden宣布支持Polygon网...
Block-986在NFT这样的市场,每周都会有相当多项目起起伏伏。在过去... -
环球今亮点!头条观察 | DeFi的兴衰与...
在比特币得到机构关注之后,许多财务专家预测世界将因为加密货币的... -
重新审视合作,体育Crypto的可靠关系才能双赢
Block-987即使在体育Crypto领域,人们的目光仍然集中在FTX上。随着... -
简讯:前端单元测试,更进一步
前端测试@2022如果从2014年Jest的第一个版本发布开始计算,前端开发... -
焦点热讯:刘强东这波操作秀
近日,刘强东发布京东全员信,信中提到:自2023年1月1日起,逐步为...