• djcelery的定时任务问题


        前几天在工作中遇到djcelery定时任务失效的问题,查了好几天,最终定位解决,整理分享下

        首先简单介绍下djcelery定时任务的框架,估计了解它的人都很熟悉,如下图

        其实简单的说就是celery的beat定时将任务发给消息中间件(这里用的是rabbitmq队列),rabbitmq将定时任务发送给celery worker去执行(即django中的task),最终将检测结果存储的过程。

        关于celery的详细介绍可见http://python.jobbole.com/87086/

        问题现象如下:

        发现一直正常运行的定时任务没有正常执行,而celery的worker和beat进程都在后台运行中,即如下的进程是存在的

        故曾经的运维经验告诉我要重启,所以,第一招,重启celery的worker和beat进程,但发现问题依旧,也就是说这个问题没法通过守护进程的方式避免。

        那第二招就是看日志了,查看worker的日志,发现其实worker已经准备好,但一直没有真正去执行任务

        下一步就是查看发生任务的消息中间件了,就是神奇的rabbitmq,rabbitmq的情况可在网页查看,如下图

        可以明显的看到queue message是没有数据的,但message rates却是有数据的(这个点其实还是没弄清到底是为什么,欢迎比较懂的同学指点)

        故尝试手动执行celery beat和worker,rabbitmq是否能收到任务,发现在djcelery的任务没有发送到rabbitmq中,手动编写测试task程序

    celeryconfig.py

    import sys
    import os
    sys.path.insert(0, os.getcwd())
    
    CELERY_IMPORTS = ("tasks", )
    
    CELERY_RESULT_BACKEND = "amqp"
    
    BROKER_HOST = "localhost"
    BROKER_PORT = 5672
    BROKER_USER = "guest"
    BROKER_PASSWORD = "guest"
    BROKER_VHOST = "/"

    tasks.py

    from celery.task import task
    from celery import Celery, platforms
    
    platforms.C_FORCE_ROOT = True
    @task
    def add(x, y):
        return x + y
                      

        执行任务,发现rabbitmq可以接受到消息,由于之前对队列的了解相当少,这里也请教了些对队列比较了解的同学,都觉得应该是消费者配置的问题,但查了django的setting没看到异常。

        查了下网上关于rabbitmq的资料,大概是生产者通过exchange将消息按照规则发送给对应的队列,而我们的队列是没有收到消息的,修改了exchange规则调试,确实队列中会收到消息,但这个队列不是我们系统制定的队列。

        在和rabbitmq纠缠了好久后,各种执行celery的命令,发现手动单独执行celery beat时会出现如下报错

        怀疑与定时任务有关,查看了报错的celery的schedules.py文件中报错的位置,初步判断是定时任务设定的问题,通过django的admin查看Periodic task的任务设置情况,发现有一个测试任务没有设置crontab和Interval,之前就遇到过当进入到这个页面,如果两个都不设置报错就会报错的情况,故将interval改为定时监测时间,crontab不设置后,celery worker日志中有数据了,rabbitmq的队列也恢复正常了。

        其实这个问题在这个文档中有一些说明

    https://my.oschina.net/kinegratii/blog/292395?fromerr=2lvw3H0L

        定时任务的重点在于必须有且仅有interval和crontab中的其一设置,即不能同时设置也不能同时不设置

        celery很强大,更多的情况可直接参考上述的两个文档,基本够用了

        而为什么会出现测试任务的定时设置的crontab和interval都为空的情况呢?由于我们的系统使用的开源项目为页面式的,在调试新功能时增加的测试任务,而修改没有涉及到后续任务执行情况的改动,故没有在admin页面设定interval和crontab,导致celery beat启动报错。

        为了避免这类的问题再次出现,进行如下的一些改进

        1、在系统页面中增加添加任务后自动设置默认的crontab和interval(省得人工去django的admin改,当然,django的admin很强大)

        2、增加celery beat单独的日志

        最后,无变更不故障,这句话我是真的体会到了

       

  • 相关阅读:
    Java 理论与实践: 正确使用 Volatile 变量
    VS2005 C++,断点无法命中的解决办法
    IndexWriterConfig的各个配置项说明(转)
    LINQ&Entity Framework
    CDN
    德鲁克之沟通的四原则
    项目管理过程之项目团队
    OOAD & OOP
    双线接入(全网路由)简单介绍
    唐僧为什么可以领导孙悟空
  • 原文地址:https://www.cnblogs.com/junyiningyuan/p/6246722.html
Copyright © 2020-2023  润新知