什么情况?DDD 中的每个任务都执行了两次?

最近在使用 COLA 框架自带的异步任务时,发现每次执行异步都执行了两次,如果一些没有做幂等的接口,这样是会有问题的,比如入库操作之类的,就会造成数据重复入库,造成严重 bug。

带着疑惑,开始了 bug 之旅。

1 问题发现

1、首先排查执行入口,是不是有两个,发现只有一个;

2、调用入口的问题?直接通过 controller 调用 handler,还是调用了两次。

3、简化代码,把 handler 内的内容都删掉,只有一个 logger 打印语句?结果还是打印了两次。

但是这次,发现 logger 的线程名不一样,是两个线程。

2023-11-26 14:11:19.429  INFO 47294 --- [pool-4-thread-2] c.e.colademo.event.handler.TestHandler   : >>>>>>>>>>>>> 0
2023-11-26 14:11:19.430  INFO 47294 --- [pool-4-thread-1] c.e.colademo.event.handler.TestHandler   : >>>>>>>>>>>>> 0

2 问题排查

为什么会有两个线程同时执行呢?查看COLA源码。

public void asyncFire(EventI event) {this.eventHub.getEventHandler(event.getClass()).parallelStream().map((p) -> {Response response = null;try {if (null != p.getExecutor()) {p.getExecutor().submit(() -> {return p.execute(event);});} else {this.defaultExecutor.submit(() -> {return p.execute(event);});}} catch (Exception var5) {response = this.handleException(p, response, var5);}return response;}).collect(Collectors.toList());
}

提交异步任务,最终都走到上面的代码,将任务提交到线程池执行,如果没有自定义线程池,那么会提交到defaultExecutor 这个默认线程池中。

发现提交了两遍,查看 this 对象中的内容,发现 Event 对象和 Handler 对象都有两个。

图1-线程池对象

event 对象有两个对应的 handler 就会执行两次。

3 问题原因

是什么原因会造成重复对象呢?

对比之前的 handler 对象,这个对象唯一的不同就是使用 @RefreshScope,查看注解源码,发现使用了这个注解的对象,都会使用代码创建一个新的对象,并在 RefreshScope 中缓存起来,debug 源码,查看缓存的对象。

图2-Scope缓存对象

发现的确有 TestHandler 对象,对象为@12349。

对比图1 中的 handler 对象,里面也有一个 TestHandler 对象,对象也是 @12349。

原来如此,因为使用了注解 @RefreshScope,这个注解会创建一个对象,这样就会有两个相同的对象,造成重复执行。

结论:使用注解 @RefreshScope 需要注意,最好把获取配置的内容放在单独的 property 对象中,不要和其他代码混用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/334756.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小巧且兼具高性能的小模型 TinyLlama 等

TinyLlama-1.1B 小模型在边缘设备上有着广泛的应用,如智能手机、物联网设备和嵌入式系统,这些边缘设备通常具有有限的计算能力和存储空间,它们无法有效地运行大型语言模型。因此,深入探究小型模型显得尤为重要。 来自新加坡科技…

搜维尔科技:第九届元宇宙数字人设计大赛作品规范解读!

作品提交 参赛小组需要将作品上传至百度网盘,并将分享链接发送至frankaxis3d.cn邮箱。邮寄格式如下: 邮件标题:作品名称元宇宙数字人设计大赛作品 邮件内容标明:学校名称、院系名称、作品名称、作者名称、联系电话及指导老师名…

Python 使用input函数从键盘输入数据

在Python中,input()函数可以从键盘获取用户的输入数据。当我们使用input()函数时,会暂停程序的执行,等待用户输入数据,并将用户输入的数据作为字符串返回。 如: name input("请输入你的姓名:"…

C#,入门教程(12)——数组及数组使用的基础知识

上一篇: C#,入门教程(11)——枚举(Enum)的基础知识和高级应用https://blog.csdn.net/beijinghorn/article/details/123917587 数组是一种数据集合,是一组完全相同的、按顺序存放的数据。 需要记住数组的几个特征&…

阿里云 WindowsServer 使用之 配置 SQL Server 允许远程连接

阿里云 WindowsServer 使用之 配置 SQL Server 允许远程连接 第一步:安装 SQL Server 数据库 这是一个很详细的安装教程,可以参考一下 安装SQL Server详细教程 需要注意:安装实例时,建议在‘身份验证模式’直接选择“混合模式”…

2023年阿里云云栖大会:前沿技术发布与未来展望

在2023年的阿里云云栖大会上,我见证了云计算和人工智能领域的又一历史性时刻。这次大会不仅是对未来科技趋势的一次深入探索,更是阿里云技术实力和创新能力的集中展示。 首先,千亿级参数规模的大模型通义千问2.0的发布,无疑将人工…

C# 日期转换“陷阱”

在 C# 中,日期转换可能会遇到一些陷阱。以下是一些常见的陷阱和如何避免它们: 时区问题 日期和时间通常与时区相关,但在转换时可能会忽略或混淆时区信息。确保在转换日期时始终考虑到时区,并使用正确的时区进行转换。 DateTime…

openai API key 提示你的卡被拒绝怎么办?

openai API key 对于IP的要求非常的严格,以前你开腾讯云、阿里云的服务器都可以绑定、现在就不行了,一定要纯净的IP才可以绑定 一、排除法 1、首先确保自己的账号是没有被封的,可以正常使用的 2、确保银行卡是可以支持openai的银行卡 3、…

Unity3d 实现直播功能(无需sdk接入)

Unity3d 实现直播功能 需要插件 :VideoCapture 插件地址(免费的就行) 原理:客户端通过 VideoCapture 插件实现推流nodejs视频流转服务进行转发,播放器实现rtmp拉流 废话不多说,直接上 CaptureSource我选择的是屏幕录制,也可以是其他源 CaptureType选择LIVE–直播形式 LiveSt…

SpringBoot+SSM项目实战 苍穹外卖(09) day9作业

继续上一节的内容,本节是作业课,要求独立完成:用户端历史订单模块、商家端订单管理模块相关业务新功能开发和已有功能优化。 目录 作业要求用户端历史订单模块查询历史订单查询订单详情取消订单再来一单 商家端订单管理模块订单搜索各个状态的…

2024年1月10日 十二生肖 今日运势

小运播报:2024年1月10日,星期三,农历十一月廿九 (癸卯年乙丑月癸酉日),法定工作日。 红榜生肖:龙、牛、蛇 需要注意:鸡、狗、兔 喜神方位:东南方 财神方位&#xff1…

《堆排序》与《Top—k》

目录 ​编辑 前言: 关于《堆排序》: 第一步:建堆 第二步:排序 《Top—K问题》 关于Top—k问题: 前言: 我们在前面的blog中,对于《堆》已经有了初步的概念,那么接下来我们可以…