Django Celery定时任务和时间设置

一、Celery加入定时任务html

Celery除了能够异步执行任务以外,还能够定时执行任务。在实例代码的基础上写个测试方法:redis

 1 #coding:utf-8
 2 from celery.task.schedules import crontab  3 from celery.decorators import periodic_task  4  
 5 @periodic_task(run_every=crontab())  6 def some_task():  7     print('periodic task test!!!!!')  8     time.sleep(5)  9     print('success') 10     return True

该代码是每分钟执行一次some_task方法。django

启动celery是使用worker。但worker不能启动定时任务。启动方式以下:服务器

1)先确保中间人是否打开,我使用redis做为中间人。可参考Redis在CentOS和Windows安装过程app

 

2)进入django项目的根目录执行以下代码启动celery的worker:异步

1 celery -A myproject worker -l info

 

其中,myproject是个人django项目名称。测试

当出现celery@xxx ready说明redis启动成功。spa

有两个任务,其中一个myapp.tasks.sendmail添加的异步处理任务。myapp.tasks.some_task是本次的定时任务。命令行

 

3)一样在django项目的根目录下再打开一个命令行界面,执行以下代码:code

1 celery -A myproject beat -l info

这个beat是检查定时任务,并启动定时任务丢给worker执行。

能够稍微等待几分钟,多执行几回任务。以下图:

 

上面的窗口是beat,下面的窗口是worker。可看到print的信息在worker中输出。

咱们甚至不用打开Django项目的服务器,就能够执行定时任务。 

二、Celery定时任务时间设置

若你以为1分钟等待时间太长。能够设置为每10秒执行一次定时任务。将上面的periodic_task修改以下:

1 @periodic_task(run_every=10)

修改代码,须要重启Celery的worker和beat。

这个run_every参数是设置定时任务的时间间隔或执行的时间。该参数设置有3种方式。

1)直接设置秒数

例如刚刚所说的10秒间隔,run_every=10,每10秒执行一次任务。1分钟便是60秒;1小时便是3600秒。

 

2)经过datetime设置时间间隔

有时直接设置秒数不方便,须要经过计算获得具体秒数。

例如,1小时15分钟40秒 = 1*60*60 + 15*60 + 40。这种状况可读性也不高。

能够采用datetime设置,代码以下:

1 from celery.decorators import periodic_task 2 import datetime 3  
4 @periodic_task(run_every=datetime.timedelta(hours=1, minutes=15, seconds=40)) 5 def some_task(): 6     print('periodic task test!!!!!')

代码可读性明显提高,并且设置方便。

但这种不能知足定时定点的时间设置。假如我想固定天天12点15分的时候,执行一次任务。datetime和直接设置秒数的方式都没法实现。这时得使用第3种方式。

 

3)celery的crontab表达式

crontab是比较完善,且稍微有点复杂(相对前面两种方式而言)的方式。能够实现咱们各类设置时间的需求。

例如,前面给出的代码:

1 #coding:utf-8
2 from celery.task.schedules import crontab 3 from celery.decorators import periodic_task 4  
5 @periodic_task(run_every=crontab()) 6 def some_task(): 7     print('periodic task test!!!!!'

表示每分钟0秒时刻执行一次(后面不提这个0秒,你们都知道就好了,省点口水)。

其中,crontab()实例化的时候没设置任何参数,都是使用默认值。crontab一共有7个参数,经常使用有5个参数分别为:

minute:分钟,范围0-59;

hour:小时,范围0-23;

day_of_week:星期几,范围0-6。以星期天为开始,即0为星期天。这个星期几还可使用英文缩写表示,例如“sun”表示星期天;

day_of_month:每个月第几号,范围1-31;

month_of_year:月份,范围1-12。

 

a、默认参数

这些参数能够设置表达式,表达稍微复杂的设置。默认值都是"*"星号,表明任意时刻。即crontab()至关与:

1 crontab(minute='*', hour='*', day_of_week='*', day_of_month='*', month_of_year='*')

含义是天天、每小时、每分钟执行一次任务。这说法太反人类语言习惯,简单说就是每1分钟执行一次任务。

 

b、具体某个值

上面提到这些参数的取值范围。咱们能够直接设置某个值。例如:

1 crontab(minute=15)

即每小时的15分时刻执行一次任务。直接指定某个时刻。以此类推能够设置天天0点0分时刻执行任务的设置以下:

1 crontab(minute=0, hour=0)

固然,也能够设置多个值。例如0分和30分执行一次任务:

crontab(minute='0,30')

这里使用字符串,用逗号隔开数值。这里的逗号是表示多个表达式or逻辑关系。

 

c、设置范围

设置范围也是设置多个值,例如指定9点到12点每一个小时的每分钟执行任务。

1 crontab(minute='*', hour='9-12')

这里*号是默认值,能够省略以下:

1 crontab(hour='9-12')

上面提到逗号是or逻辑关系。拓展一下,指定9点到12点和20点中每分钟执行任务:

1 crontab(hour='9-12,20')

crontab的表达式愈来愈复杂了。celery还提供了一个类获得表达式解析结果,代码以下:

1 from celery.task.schedules import crontab_parser 2 r = crontab_parser(23, 0).parse('9-12,20') 3 print(r)

其中,crontab_parse是一个解析类。第1个参数是范围的最大值;第2个参数是范围的最小值。经过parse输入表达式,可获得表达式的解析结果:

1 set([9, 10, 11, 12, 20])

下面不少地方咱们均可以经过该方法验证解析结果。

  

d、设置间隔步长

假如我要设置一、三、五、七、九、11月份天天每分钟执行任务,按照上面的作法能够设置以下:

1 crontab(day_of_month='1,3,5,7,9,11')

观察数据能够发现,都是间隔2的步长。须要设置的数字比较少,若数字比较多显得很麻烦。例如我想每间隔2分钟就执行一次任务,要写30个数字想一想就以为很麻烦。crontab表达式还提供了间隔的处理,例如:

1 crontab(minute='*/2') 2 crontab(minute='0-59/2') #效果等同上面

这个/号不是除以的意思。至关与range的第3个参数,例如:

1 range(0, 59+1, 2)

差很少crontab表达式就这些,多举几个例子:

 1 #每2个小时中每分钟执行1次任务
 2 crontab(hour='*/2')  3  
 4 #每3个小时的0分时刻执行1次任务
 5 #即[0,3,6,9,12,15,18,21]点0分
 6 crontab(minute=0, hour='*/3')  7  
 8 #每3个小时或8点到12点的0分时刻执行1次任务
 9 #即[0,3,6,9,12,15,18,21]+[8,9,10,11,12]点0分
10 crontab(minute=0, hour='*/3,8-12') 11  
12 #每一个季度的第1个月中,天天每分钟执行1次任务
13 #月份范围是1-12,每3个月为[1,4,7,10]
14 crontab(month_of_year='*/3') 15  
16 #每个月偶数天数的0点0分时刻执行1次任务
17 crontab(minute=0, hour=0, day_of_month='2-31/2') 18  
19 #每一年5月11号的0点0分时刻执行1次任务
20 crontab(0, 0, day_of_month='11', month_of_year='5')
相关文章
相关标签/搜索