V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
fanne
V2EX  ›  Django

django 定时任务选用哪种方式?

  •  
  •   fanne · 2017-04-12 11:50:41 +08:00 · 10325 次点击
    这是一个创建于 2543 天前的主题,其中的信息可能已经有所发展或是发生改变。

    背景环境如下:

    我有一个表单,用来选定时间,然后提交任务的,表单如下:

    当提交表单后,服务端要等到这个时间后开始执行一些内容,所以我的服务端需要一个定时任务。 我现有的环境已经用了 celery+redis 跑一些异步任务,所以想在此基础上直接使用 celery 做定时任务,但现在遇到一些问题。

    看官方文档中配置内容,定时任务时间写在了 /proj/celery.py 文件中,如下:

    from __future__ import absolute_import, unicode_literals
    import os
    from celery import Celery
    from django.conf import settings
    from datetime import timedelta
    from celery.schedules import crontab
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proj.settings')
    app = Celery('proj')
    app.config_from_object('django.conf:settings')
    app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
    
    
    app.conf.update(
        CELERYBEAT_SCHEDULE = {
            'do-task-every-30-seconds': {
                'task': 'items.taskWork.do_task',
                # 'schedule': timedelta(seconds=10),
                'schedule': crontab(hour=11, minute=32, day_of_month=12,month_of_year=4),
            },
        },
    )
    
    
    @app.task(bind=True)
    def debug_task(self):
        print('Request: {0!r}'.format(self.request))
    

    其中 app.conf.update 中内容即为执行任务的时间设定。

    定时任务写在了 /proj/items/taskWork.py

    @shared_task
    def do_task():
       print ('run by celery 23333~~~ dddddddd')
    

    那么,按照这样的设定,我每增加一个任务,难不成都得生成一条app.conf.update的内容到 /proj/celery.py 中?这个怎么看怎么不合理的感觉。

    我也翻了 django-crontab 内容,然后发现它这个是把定时任务写到 setting.py 文件中。若我每次生成一个人也得每次写一条记录到 setting.py 中,也貌似不怎么合理。而且我目前项目没有去用 django-admin 内容的,所以没法用 django-admin 中的 crontab 功能。

    所以,类似这种,经常添加定时任务的内容,要怎么操作? 假设在 django+celery+redis 环境下要怎么操作?

    6 条回复    2017-04-12 14:47:29 +08:00
    wingor
        1
    wingor  
       2017-04-12 12:20:34 +08:00
    apscheduler
    gotounix
        2
    gotounix  
       2017-04-12 13:08:55 +08:00
    我前几天在 Flask 项目中有这个需求,看了下 Django 的相关项目,楼主可以看下官方的 django-celery-beat 这个项目,定时任务的结果可以参考官方的 django-celery-results 项目。
    chenqh
        3
    chenqh  
       2017-04-12 13:54:04 +08:00
    crontab?
    ytmsdy
        5
    ytmsdy  
       2017-04-12 14:36:03 +08:00
    新建任务后,存到任务记录表里面,标记状态为 0 。
    调用 django-crontab ,每一分钟扫描一下未执行的记录。
    如果发现当前时间和设置的时间一致,则执行,并更新任务状态。
    fanne
        6
    fanne  
    OP
       2017-04-12 14:47:29 +08:00
    @wingor @gotounix @jimmyye @ytmsdy
    我用 1 楼的方案研究出了一点眉目,但有点新问题
    我的 scheduler_task 内容:
    def task():
    print 'dddddddddddd'

    def scheduler_task(curdata):
    import logging
    task_logger = logging.getLogger('items.taskWork')
    scheduler = BackgroundScheduler()
    scheduler.add_jobstore('redis',jobs_key='kaifu.jobs',run_times_key='kaifu.run_times')
    scheduler.add_job(task,'date',next_run_time='%s' %curdata)
    scheduler._logger = task_logger
    try:
    scheduler.start()
    except(KeyboardInterrupt,SyntaxError):
    scheduler.shutdown()

    用了 redis 存储任务列表, curdata 是接收表单的那个时间,经测试过,可以正常实现功能,然后新问题是,我添加一个新的任务列表后,我重启项目后,时间到点了,任务就无法执行了,这个要怎么改进?

    PS ,谁知道 回复 这里代码格式化要怎么搞?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5465 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 06:03 · PVG 14:03 · LAX 23:03 · JFK 02:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.