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


    一、背景

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

    二、分析

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

    使用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]
    
    • 1
    • 2
    • 3
    • 4

    从返回的日志也可以看出,确实是在同一时间,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分钟到误差。

  • 相关阅读:
    Leetcode -2
    功能安全 ISO26262
    网上商城项目(加入购物车)
    商城项目03_人人前后端项目、逆向工程、common工程搭建、coupon以及各个微服务工程搭建
    Python文件操作:读取、打开、写入、关闭、按行读取、文件指针(附零基础学习资料)
    【飞控调试】DJIF450机架+Pixhawk6c mini+v1.13.3固件+好盈Platinium 40A电调无人机调试
    “为了买台手机,研究大半个月后仍然无从选择”
    创建线程池执行java代码逻辑
    祥云杯2022 pwn - sandboxheap
    线性空间的定义与性质
  • 原文地址:https://blog.csdn.net/qq_21918903/article/details/126663161