天天看点

django+celery 实现定时任务

利用 celery 实现定时任务

  celery支持定时任务,设定好任务的执行时间,celery就会定时自动帮你执行, 这个定时任务模块叫celery beat

Celery安装

由于celery 4.0 ,不再支持 Windows,故我们使用celery3.1.26 在windows环境下进行测试

安装:

pip install celery==3.1.26.post2 django-celery==3.2.2 flower==0.9.2      

 Django中配置

在主项目的配置文件settings.py 中应用注册表INSTALLED_APPS中加入 djcelery

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01.apps.App01Config',
    'djcelery',  #加入djcelery
]      

 在settings.py 中配置celery信息

import djcelery

# 当djcelery.setup_loader()运行时,Celery便会去查看INSTALLD_APPS下包含的所有app目录中的tasks.py文件,找到标记为task的方法,将它们注册为celery task。
djcelery.setup_loader()

#broker是代理人,它负责分发任务给worker去执行。此处用的是是Redis作为broker
BROKER_URL = 'redis://127.0.0.1:6379/1' 
# 导入目标任务文件
CELERY_IMPORTS = ('app01.tasks')
# 设置时区
CELERY_TIMEZONE = 'Asia/Shanghai'

#表示使用了django-celery默认的数据库调度模型,任务执行周期都被存在默认指定的orm数据库中.
CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler' 

from celery.schedules import crontab
from celery.schedules import timedelta

# 下面是定时任务的设置,我一共配置了三个定时任务.
from celery.schedules import crontab
CELERYBEAT_SCHEDULE = {
    #定时任务一: 每24小时周期执行任务(test1)
    u'任务一': {
        "task": "app01.tasks.test1",
        "schedule": crontab(hour='*/24'),
        "args": (),
    },
    #定时任务二: 每天的凌晨12:30分,执行任务(test2)
    u'任务二': {
        'task': 'app01.tasks.test2',
        'schedule': crontab(minute=30, hour=0),
        "args": ()
    },
    #定时任务三:每个月的1号的6:00启动,执行任务(test3)
    u'任务三': {
            'task': 'app01.tasks.test3',
            'schedule': crontab(hour=6, minute=0,  day_of_month='1'),
            "args": ()
    },
}      

 创建应用实例

主工程目录添加celery.py, 添加自动检索django工程tasks任务

​ project/celery.py

#目的是拒绝隐士引入,celery.py和celery冲突。
 from __future__ import absolute_import,unicode_literals import os 
from celery import Celery 
from django.conf import settings
 ​ 
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings") ​ 
#创建celery应用 
app = Celery('project') 
#You can pass the object directly here, but using a string is better since then the worker doesn’t have to serialize the object.
app.config_from_object('django.conf:settings')

#如果在工程的应用中创建了tasks.py模块,那么Celery应用就会自动去检索创建的任务。比如你添加了一个任#务,在django中会实时地检索出来。 
app.autodiscover_tasks(lambda :settings.INSTALLED_APPS)      

创建任务 tasks

每个任务本质上就是一个函数,在tasks.py中,写入你想要执行的函数即可

from artproject.celery import app

@app.task
def test1()
    pass


@app.task
def test2()
    pass

@app.task
def test2()
    pass      

启动定时任务

启动celery beat周期任务命令:

用于启动beater,它就像一个领导,负责把任务分发给工人。

celery -A proj beat      

启动Celery Worker来开始监听并执行任务

beat与worker也可以同时启动,但最好只用于测试,适用于只启动一个worker节点的情况:

用于启动worker, worker本质上执行任务的线程,就是一个干苦力的工人。

celery -A proj worker      

beat会在当前目录下建立一个文件celerybeat-schedule来记录任务上次运行的时间,所以要保证celery对当前目录有写入的权限,或者指定文件位置:

celery -A proj beat -s /home/celery/var/run/celerybeat-schedule      

supervisor管理celery

 先在etc/supervisord.d目录下创建一个名为uwsgi_statrt.ini的配置文件

[program:redis]
;指定运行目录
user=root 
;执行命令(redis-server redis配置文件路径)
command=redis-server /usr/local/etc/redis.conf
; 
; ;启动设置 
numprocs=1          ;进程数
autostart=true      ;当supervisor启动时,程序将会自动启动 
autorestart=true    ;自动重启

;停止信号,默认TERM 
;;中断:INT (类似于Ctrl+C)(kill -INT pid),退出后会将写文件或日志(推荐) 
;;终止:TERM (kill -TERM pid) 
;;挂起:HUP (kill -HUP pid),注意与Ctrl+Z/kill -stop pid不同 
;;从容停止:QUIT (kill -QUIT pid) 
;stopsignal=INT  
;  ;停止信号
stopsignal=INT

;输出日志 
stdout_logfile=/var/log/supervisor/redis.log
stdout_logfile_maxbytes=10MB  ;默认最大50M
stdout_logfile_backups=10     ;日志文件备份数,默认为10
;; 
;错误日志 
redirect_stderr=false         ;为true表示禁止监听错误
stderr_logfile=/var/log/supervisor/redis_err.log
stderr_logfile_maxbytes=10MB
stderr_logfile_backups=10



[program:celery.worker] 
;指定运行目录 
user=root
directory=/home/project/thinking_library
;运行目录下执行命令
command=/home/env/thinking_library/bin/celery -A thinking_library  worker --loglevel info --logfile celery_worker.log
; 
; ;启动设置 
numprocs=1          ;进程数
autostart=true      ;当supervisor启动时,程序将会自动启动 
autorestart=true    ;自动重启
;  
;  ;停止信号,默认TERM 
;  ;中断:INT (类似于Ctrl+C)(kill -INT pid),退出后会将写文件或日志(推荐) 
;  ;终止:TERM (kill -TERM pid) 
;  ;挂起:HUP (kill -HUP pid),注意与Ctrl+Z/kill -stop pid不同 
;  ;从容停止:QUIT (kill -QUIT pid) 
stopsignal=INT

;输出日志 
stdout_logfile=/var/log/supervisor/celery_worker.log 
stdout_logfile_maxbytes=10MB  ;默认最大50M 
stdout_logfile_backups=10     ;日志文件备份数,默认为10 
; 
; ;错误日志 
redirect_stderr=false         ;为true表示禁止监听错误 
stderr_logfile=/var/log/supervisor/celery_worker_err.log 
stderr_logfile_maxbytes=10MB 
stderr_logfile_backups=10



[program:celery.beat] 
;指定运行目录 
user=root
directory=/home/project/thinking_library
;;运行目录下执行命令
command=/home/env/thinking_library/bin/celery -A thinking_library worker --loglevel info --logfile celery_beat.log
; 
; ;启动设置 
numprocs=1          ;进程数
autostart=true      ;当supervisor启动时,程序将会自动启动 
autorestart=true    ;自动重启
;  
;  ;停止信号
stopsignal=INT

;输出日志 
stdout_logfile=/var/log/supervisor/celery_beat.log 
stdout_logfile_maxbytes=10MB  ;默认最大50M 
stdout_logfile_backups=10     ;日志文件备份数,默认为10 
; 
; ;错误日志 
redirect_stderr=false         ;为true表示禁止监听错误 
stderr_logfile=/var/log/supervisor/celery_worker_err.log 
stderr_logfile_maxbytes=10MB 
stderr_logfile_backups=10      

celeryworker.ini

错误提醒:

测试时启动过一次Beat,beat按理说是只能启动一个的但是不服务器都重启过了还是提示已有进程在运行。

ERROR: Pidfile (celerybeat.pid) already exists. Seems we're already running? (pid: 11068)

解决方法:

删除项目下 celertbeat.pid文件即可

转载于:https://www.cnblogs.com/freely/p/9550163.html