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分钟到误差。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Celeryapply_async()方法是用于处理异步任务的常见API。通过调用apply_async()方法,可以将任务丢给Celery,让一个进程去执行任务。这个方法的逻辑是创建一个Celery任务,然后在任务执行之前再次调用apply_async()方法,指定下次执行定时时间。这样就会产生一个定时Celery worker。任务执行时,会处理相应的业务逻辑。当达到定时时间时,定时Celery worker开始执行,然后循环回到第一步。\[1\]\[3\] 然而,有时候在使用apply_async()接口时可能会出现问题。比如,任务可能会丢失,就像将一个石头丢进了大海里一样,消失了。这可能是因为在使用异步调用时出现了故障,而同步调用则没有问题。对于这种情况,需要仔细检查代码和配置,确保正确地使用apply_async()方法,并且没有其他错误导致任务丢失。\[2\] #### 引用[.reference_title] - *1* [celery apply_async定时任务重复执行问题](https://blog.csdn.net/qq_21918903/article/details/126663161)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Celeryapply_async()无法正常工作的解决方案之一](https://blog.csdn.net/inter_peng/article/details/104706810)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值