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

2017-04-12 11:50:41 +08:00
 fanne

背景环境如下:

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

当提交表单后,服务端要等到这个时间后开始执行一些内容,所以我的服务端需要一个定时任务。 我现有的环境已经用了 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 环境下要怎么操作?

10346 次点击
所在节点    Django
6 条回复
wingor
2017-04-12 12:20:34 +08:00
apscheduler
gotounix
2017-04-12 13:08:55 +08:00
我前几天在 Flask 项目中有这个需求,看了下 Django 的相关项目,楼主可以看下官方的 django-celery-beat 这个项目,定时任务的结果可以参考官方的 django-celery-results 项目。
chenqh
2017-04-12 13:54:04 +08:00
crontab?
jimmyye
2017-04-12 14:05:53 +08:00
ytmsdy
2017-04-12 14:36:03 +08:00
新建任务后,存到任务记录表里面,标记状态为 0 。
调用 django-crontab ,每一分钟扫描一下未执行的记录。
如果发现当前时间和设置的时间一致,则执行,并更新任务状态。
fanne
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 ,谁知道 回复 这里代码格式化要怎么搞?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/354302

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX