当前位置: 首页 > news >正文

celery apply_async定时任务重复执行问题

一、背景

清晨起来,客户生产环境突然出现诡异的现象,定时早上7点执行一次的任务,在七点执行了七八次,非常诡异。而且经过排查,发现没有报错信息,最后是查看日志时,发现celery重发了很多同一时间的定时任务。

二、分析

代码逻辑
run_task.apply_async(args=[xx,xx], eta=start_time)

使用celery apply_async定时函数来实现定时周期任务,逻辑如下:

  1. 创建一个celery任务。
  2. 任务执行之前,再次调用apply_async函数,指定下次执行的定时时间。此时会产生一个定时的celery worker。
  3. 任务执行,处理业务逻辑。
  4. 达到定时时间,定时的celery worker开始执行,循环第1步。

从上面可以看出,这个逻辑是可以实现定时的周期任务,而且经过验证,但定时时间不超过一个小时的时候,是可以正常周期执行任务的。但是,当定时时间超过一天时,开始出现问题,一次定时任务,出现多次执行的现象。

日志
[2022-08-31 07:00:01,254: INFO/MainProcess] Received task: run_task[9f92844c-8cb8-458e-9917-99d51c80b0a8] eta:[2022-09-07 07:00:00]
[2022-08-31 07:00:01,297: INFO/MainProcess] Received task: run_task[f39a9992-fb5f-415e-824a-955b522d2fa7] eta:[2022-09-08 07:00:00]
[2022-08-31 07:00:01,379: INFO/MainProcess] Received task: run_task[7610c9e3-b4d9-48a1-9357-8f49d9c9fa08] eta:[2022-09-09 07:00:00]
[2022-08-31 07:00:01,423: INFO/MainProcess] Received task: run_task[0a2ff57c-eefd-4aac-9586-2d96ac761821] eta:[2022-09-10 07:00:00]

从返回的日志也可以看出,确实是在同一时间,celery产生了四个相同的worker。

原因

出现这个现象,很可能和celery的重传机制有关。
查到一篇文章《Celery ETA任务重复提交的问题解决》,有解释这个现象。

celery对ETA/countdown/retry等要求具体时间执行的任务支持并不完整. 指定执行时间,与celery自身的失效重传机制有所冲突.
celery在没有收到任务被worker正常执行的时候就会发起重传.我项目中的ETA任务往往是在24小时之后才执行, celery的默认重传timeout是1个小时(Visibility timeout).因此理论上在ETA时间没有到之前,celery每过一个小时便重复提交一个任务给worker

三、解决办法

修改定时周期任务逻辑,不使用apply_async实现定时周期任务,可以起一个周期执行任务,每隔两分钟执行一次,去扫描达到执行时间的定时任务,同样可以实现定时周期任务,只是任务执行可能存在0-2分钟到误差。

相关文章:

  • 接口测试基本知识点
  • C++学习记录4
  • JSP企业内部交流系统myeclipse开发mysql数据库bs框架java编程jdbc
  • 关于获得淘宝商品评论的那些事
  • 资深工程师整理2022年最新面试题汇总
  • 打破程序员“中年危机”8年测试工程师经验之谈
  • 资深架构师必备知识:Netty+MySQL+并发+JVM+多线程
  • java移动端选课系统设计与实现服务器端计算机毕业设计MyBatis+系统+LW文档+源码+调试部署
  • hadoop historyserver启动,无法访问,查看报错等问题
  • Worthington公司刀豆蛋白A的特性及参考文献
  • 面试算法 二叉树的遍历,方法 :线索二叉树 ( morris ) ,前序遍历: 中序遍历: 后序遍历
  • Google Earth Engine(GEE)——一个简单的影像波段时序折现图
  • Pytorch神经网络设计技巧-如何得到各层的input shape
  • 21-mvc 体系结构源码详解
  • 22-Spring MVC源码跟踪
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • ECMAScript6(0):ES6简明参考手册
  • If…else
  • Redis学习笔记 - pipline(流水线、管道)
  • socket.io+express实现聊天室的思考(三)
  • webpack4 一点通
  • 程序员该如何有效的找工作?
  • 后端_ThinkPHP5
  • 类orAPI - 收藏集 - 掘金
  • 聊聊sentinel的DegradeSlot
  • 七牛云 DV OV EV SSL 证书上线,限时折扣低至 6.75 折!
  • 前端
  • 深度学习入门:10门免费线上课程推荐
  • ​Z时代时尚SUV新宠:起亚赛图斯值不值得年轻人买?
  • #Lua:Lua调用C++生成的DLL库
  • $refs 、$nextTic、动态组件、name的使用
  • %3cli%3e连接html页面,html+canvas实现屏幕截取
  • (9)目标检测_SSD的原理
  • (HAL库版)freeRTOS移植STMF103
  • (大众金融)SQL server面试题(1)-总销售量最少的3个型号的车及其总销售量
  • (转)jQuery 基础
  • .equals()到底是什么意思?
  • .naturalWidth 和naturalHeight属性,
  • .NET 4 并行(多核)“.NET研究”编程系列之二 从Task开始
  • .net core 依赖注入的基本用发
  • .NET 简介:跨平台、开源、高性能的开发平台
  • .NET 中选择合适的文件打开模式(CreateNew, Create, Open, OpenOrCreate, Truncate, Append)
  • .NET/C# 中你可以在代码中写多个 Main 函数,然后按需要随时切换
  • @ 代码随想录算法训练营第8周(C语言)|Day57(动态规划)
  • @Async注解的坑,小心
  • @SuppressWarnings注解
  • [AR]Vumark(下一代条形码)
  • [C#]使用PaddleInference图片旋转四种角度检测
  • [hdu 4405] Aeroplane chess [概率DP 期望]
  • [HDU5685]Problem A
  • [hive小技巧]同一份数据多种处理
  • [JS入门到进阶] 哎,被vite小坑了一波,大家记得配置build.cssTarget为‘chrome61‘
  • [oeasy]python001_先跑起来_python_三大系统选择_windows_mac_linux
  • [POJ1236]Network of Schools(并查集+floyd,伪强连通分量)
  • [raspberry pi3] 串口线使用