1、Celery加入异步和定时任务

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

import datetime
import timefrom celery import shared_task
from celery.schedules import crontab
from celery.task import periodic_taskfrom FruitGP2.utils import send_active_email@shared_task
def send_activate_email_async(username,to_email):send_active_email(username,to_email)@periodic_task(run_every=datetime.timedelta(hours=1, minutes=15, seconds=40))
@periodic_task(run_every=10)
def some_task():print('periodic task test!!!!!')# celery -A FruitShopGP2  beat -l info
# celery -A FruitShopGP2  worker -l info# @periodic_task(run_every=crontab())
# def some_task():
#      print('periodic task test!!!!!')
#      print('success')

settings.py

# Celery settingsCELERY_BROKER_URL = 'redis://:@localhost:6379/0'#: Only add pickle to this list if your broker is secured
#: from unwanted access (see userguide/security.html)
CELERY_ACCEPT_CONTENT = ['json']
# CELERY_RESULT_BACKEND = 'db+sqlite:///results.sqlite'
CELERY_RESULT_BACKEND = 'django-db'
CELERY_TASK_SERIALIZER = 'json'

celery.py

from __future__ import absolute_import, unicode_literalsimport osfrom celery import Celery# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'FruitShopGP2.settings')app = Celery('FruitShopGP2')# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
#   should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings', namespace='CELERY')# Load task modules from all registered Django app configs.
app.autodiscover_tasks()@app.task(bind=True)
def debug_task(self):print('Request: {0!r}'.format(self.request))

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

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

1)先确保中间人是否打开,我使用redis作为中间人。可参考

http://docs.celeryproject.org/en/master/getting-started/first-steps-with-celery.html#redis

https://github.com/celery/celery/blob/master/examples/django/proj/settings.py

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

 celery -A FruitShopGP2 worker -l info

其中,myproject是我的django项目名称。

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

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

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

   celery -A FruitShopGP2  beat -l info

可以稍微等待几分钟,多执行几次任务。如下图 上面的窗口是beat,下面的窗口是worker。可看到print的信息在worker中输出。

我们甚至不用打开Django项目的服务器,就可以执行定时任务。

下方内容仅供参考:

2、Celery定时任务时间设置

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

 @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、设置间隔步长

假如我要设置1、3、5、7、9、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')

celery 学习笔记定时任务和异步任务相关推荐

  1. celery 学习笔记 01-介绍

    celery 学习笔记 01-介绍 celery 是 python 中的常用的任务队列框架,经常用于异步调用.后台任务等工作.celery 本身以 python 写,但协议可在不同的语言中实现,其它语 ...

  2. Celery 学习笔记(2)- 定时任务

    定时任务 Celery 中启动定时任务有两种方式,(1)在配置文件中指定:(2)在程序中指定. # cele.py import celeryapp = celery.Celery('cele', b ...

  3. flask、celery+redis 实现定时任务和异步——(一)

    1. Celery简介 Celery是一个异步任务的调度工具. Celery 是 Distributed Task Queue,分布式任务队列,分布式决定了可以有多个 worker 的存在,队列表示其 ...

  4. celery学习笔记

    celery -消息队列 -异步任务 -定时任务 -需要了解的知识 -选择并安装消息容器(载体) -安装celery并创建第一个任务 -开启工作进程并调用任务 -记录工作状态和返回的结果 Celery ...

  5. celery学习笔记:celery安装,并运行第一个应用

    1.celery通过消息进行通信,通常使用一个叫Broker(中间人)来协client(任务的发出者)和worker(任务的处理者). clients发出消息到队列中,broker将队列中的信息派发给 ...

  6. 学习笔记二:异步FIFO

    1 module fifo1 #(parameter DSIZE = 8, 2 parameter ASIZE = 4) //用格雷码的局限性:循环计数深度必须是2的n次幂,否则就失去了每次只变化一位 ...

  7. android学习笔记---64_ListView数据异步加载与AsyncTask

    2013/5/26 Java技术qq交流群:JavaDream:251572072 64_ListView数据异步加载与AsyncTask ------------------------------ ...

  8. Celery 学习笔记(3)- 任务和任务执行

    任务 任务是 Celery 里不可缺少的一部分,它可以是任何可调用对象.每一个任务通过一个唯一的名称进行标识, worker 通过这个名称对任务进行检索.任务可以通过 app.task 装饰器进行注册 ...

  9. Dart 学习笔记一(操作符、方法与异常)

    目录 Dart变量 final和const修饰符 Dart的内置类型 numbers Strings Booleans Lists(列表) Maps(映射集合) Runes(用于在字符串中表示Unic ...

最新文章

  1. SQL2005 BCP
  2. MXNET学习笔记(二):模型的保存与加载
  3. 密码认证协议PAT怎么配置?
  4. mysql 备份文件太大_mysql数据库太大了怎么备份
  5. php 画图 坐标,说说PHP作图(一)_php
  6. 使用 ODP.NET 访问 Oracle(.net如何访问Oracle)详解
  7. linux cron 服务,Linux定时任务Crontab详解(推荐)
  8. 28. Location replace() 方法
  9. python mssql get image bin_python 使用pymssql连接sql server数据库
  10. Java 常见异常类
  11. 回顾:程序设计方法——结构化设计
  12. 苹果个人开发者账号出售_国内苹果企业级开发者账号申请需要多久
  13. 高效沟通的5个原则,解决90%的沟通问题
  14. 机器人运动学标定:基于指数积的串联机构运动学标定
  15. 巾帼绽芬芳 一起向未来(中篇)
  16. 58. 最后一个单词的长度(水题)
  17. matlab求系统状态时间响应,MATLAB求解系统零状态响应可以调用( )函数。
  18. 智慧家庭解决方案-最新全套文件
  19. sqlDbx连接oracle64位
  20. java8 集合的交集、并集、差集

热门文章

  1. 视频中场的问题2009-04-03 19:38(一)
  2. 解决:ClassNotFoundException: com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect
  3. 视界云:CDN{内容分发网络} 知识详解
  4. JavaScript onerror 事件( window.onerror = )
  5. 树链剖分 讲解+模板+习题
  6. P4313 文理分科 网络流
  7. BZOJ.2780.[SPOJ8093]Sevenk Love Oimaster(广义后缀自动机)
  8. unittest核心要素
  9. 【BZOJ 1597】 [Usaco2008 Mar]土地购买 (斜率优化)
  10. display:flex