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

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

1 问题发现

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

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

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

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

2021-07-26 14:11:19.429  INFO 47294 --- [pool-4-thread-2] c.e.colademo.event.handler.TestHandler   : >>>>>>>>>>>>> 0
2021-07-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对象都有两个。

3 问题原因

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

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

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

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

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

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

COLA异步任务重复执行?相关推荐

  1. Celery异步任务重复执行(Redis as broker)

    之前讲到利用celery异步处理一些耗时或者耗资源的任务,但是近来分析数据的时候发现一个奇怪的现象,即是某些数据重复了,自然想到是异步任务重复执行了. 查阅之后发现,到如果一个任务太耗时,任务完成时间 ...

  2. Android按钮持续按下执行,Android 按钮长按下去重复执行某个动作,放开后停止执行动作...

    Android开发中,常遇到一种需求,即按钮长按下去重复执行某个动作,放开后停止执行动作.网上找了许多代码,都没有适合的,于是自己动手写了一个. 基本思路是:首先设置一个标识变量,用于标识是否处于按下 ...

  3. 同步异步、JS执行机制、事件循环

    文章目录 单线程 同步 异步 同步任务 异步任务 JS执行机制 异步进程处理 事件循环-event loop(这里主要是说浏览器事件循环) 单线程 JS的一大特点就是单线程,也就是同一时间内只能做一件 ...

  4. linux使用flock文件锁解决脚本周期内未执行完重复执行

    linux使用flock文件锁解决脚本周期内未执行完重复执行 关于flock flock 是对于整个文件的建议性锁.也就是说,如果一个进程在一个文件(inode)上放了锁,那么其它进程是可以知道的.( ...

  5. 【青少年编程】【答疑】控制Scratch异步代码的执行顺序

    问题 几天前,我写了一篇图文 对「等待(0)秒」的理解,发现可以利用「等待(0)秒」这个积木块来解决Scratch中异步代码的执行顺序问题,即点击绿旗后可以控制多个角色中响应该事件的代码的顺序. 在这 ...

  6. Spring的quartz定时器重复执行二次的问题解决

    Spring的quartz定时器重复执行二次的问题解决 参考文章: (1)Spring的quartz定时器重复执行二次的问题解决 (2)https://www.cnblogs.com/alamps/p ...

  7. 【OkHttp】OkHttp 源码分析 ( 同步 / 异步 Request 请求执行原理分析 )

    OkHttp 系列文章目录 [OkHttp]OkHttp 简介 ( OkHttp 框架特性 | Http 版本简介 ) [OkHttp]Android 项目导入 OkHttp ( 配置依赖 | 配置 ...

  8. python重复执行_关于计时器:在Python中每x秒重复执行一次函数的最佳方法是什么?...

    我想永远每60秒在Python中重复执行一个函数(就像目标C中的NSTimer一样). 这段代码将作为守护进程运行,实际上就像使用cron每分钟调用python脚本一样,但不需要用户设置. 在这个关于 ...

  9. sudo: apt-get:找不到命令_Linux重复执行历史命令方法详解

    Linux 下,如果要执行一条或多条之前输过的指令,要怎么处理?很多人会想到使用上下箭头去翻查历史输入的命令.这当然是可以了,除了这种方法,本文再介绍另外 5 种方法来实现这样的效果. 在正式开始之前 ...

最新文章

  1. mysql 高并发加锁_Mysql高并发加锁事务处理
  2. illegal base64 character 3a_双11华硕多款产品再送豪礼 高端硬件通吃最新3A大作
  3. 使用ExtJs创建新的UI控件(转)
  4. 内网更新服务器的搭建(WSUS)
  5. CSS3学习——设计优雅的数据表格
  6. 哪一个不是linux常用的shell,Linux下查看使用的是哪种shell的方法汇总
  7. 家用简单电线路图_家庭配电箱接线图解 家用配电箱安装方法
  8. mysql duplicate key与replace into对比
  9. 【渝粤题库】陕西师范大学200131中国古代文论 作业(专升本)
  10. python常用函数中文_【python】python常用函数
  11. 微信小程序php实现登陆的代码,微信小程序实现微信登录
  12. 【重难点】【JUC 01】线程安全都体现在哪些方面 、如何维护线程安全、多线程的同步方法、多线程通信方式、AQS
  13. 【免费毕设】PHP论文格式化系统(系统+论文)
  14. tsd3dmapper软件使用方法_mybatis-plus的使用 ------ 入门
  15. linux 安装vlc源码包,linux Centons 6.5 下yum安装vlc
  16. 看看五年MacBook使用经验平常都用那些软件
  17. 【英语阅读】经济学人 | 人脸识别不只是另一种技术。它将改变社会
  18. 番外篇:常见安全漏洞及解决方案
  19. Dubblo +zookeep+sprinboot注册发现 (二)来源与狂神
  20. Tekla图纸二次开发课程

热门文章

  1. 【STM32学习笔记】(13)——外部中断详解
  2. WIN10下如何更改微信聊天记录的默认存储路径
  3. 计算机按键被粘了一样,电脑总是自动重复按键盘上的一个键 经验告诉你该这样...
  4. 计算机化工应用答案,计算机化工应用习题与解答.pdf
  5. PostgreSQL学习篇9.3 浮点数类型
  6. 离散数学(一):命题及命题联结词
  7. 查看Windows凭据和普通凭据的密码(查看Windows中存储的密码)——mimikatz
  8. 你有“隐私泄露担忧”吗?适合普通用户的6个方法来了
  9. zookeeper安装及简单应用
  10. 参数维纳滤波(Parametric Wiener Filter)