celery 学习笔记定时任务和异步任务

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')

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/456244.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FBV(function base views) 顾名思义基于函数的视图类 CBV(class base views)基于类的视图类

一. 概念 FBV(function base views) 顾名思义基于函数的视图类 CBV(class base views)基于类的视图类 至于区别呢? 我觉得只是写法上的不一样, 实现的结果都是一样的, 我比较喜欢用CBV模式, 因为在Django中内部帮我做了请求方式…

rpm查询

rpm -q 的用法:1、 rpm -qa 可以查看所有已经安装过的rpm包2、rpm -qf 文件名绝对路径,可以查看该文件由哪个包安装的3、 rpm -ql 包名,可以查看该包安装哪些文件4、 rpm -qi 包名,可以查看该包的详细信息查询一个包是否安装命令&…

IntelliJ idea学习资源

工作需要, 最近得从Eclipse转战到Idea, 找了些不错的学习资料: 1, 从eclipse上迁移过来的用户说明: https://www.jetbrains.com/help/idea/2016.3/eclipse.html 2, 极客学院的idea使用入门教程: http://wiki.jikexueyuan.com/project/intellij-idea-tutorial/project-compositi…

linux下的安装:openssl

openssl简介 openssl是一个功能丰富且自包含的开源安全工具箱。它提供的主要功能有:SSL协议实现(包括SSLv2、SSLv3和TLSv1)、大量软算法(对称/非对称/摘要)、大数运算、非对称算法密钥生成、ASN.1编解码库、证书请求(PKCS10)编解码、数字证书编解码、CRL编解码、OC…

使用WinIO库实现保护模式下的IO和内存读写

问题已解决: 原因是函数的调用方式与WinIO中不一致,使用的时候漏掉了__stdcall。 函数原定义为: 在实际的GPIO读写中遇到以下问题: SetPortVal可正常写入,但是GetPortVal无法读取,程序崩溃,问题…

php 一些个 常用 函数

urlencode()函数原理就是首先把中文字符转换为十六进制,然后在每个字符前面加一个标识符%。urldecode()函数与urlencode()函数原理相反,用于解码已编码的 URL 字符串,其原理就是把十六进制字符串转换为中文字符json_decode(json,true); 输出的…

windows10中远程访问凭据不工作

远程同学电脑,发现输入账号密码还是不行,提示您的凭据不工作,问题解决:WinR---gpedit.msc网络访问----经典。转载于:https://blog.51cto.com/germa66/1934745

pycharm的 crtl + r 使用正则表达式进行 request-header格式更改

pycharm的 crtl r 使用正则表达式进行 request-header格式更改 复制粘贴之前 使用 ‘’‘ ’‘’ 保证格式不乱 改为正确格式

Android(组件大全)

ORM: Android GreenDao sqlite UI: Snackbar是Android支持库中用于显示简单消息并且提供和用户的一个简单操作的一种弹出式提醒。当使用Snackbar时,提示会出现在消息最底部,通常含有一段信息和一个可点击的按钮。Support Design Library转载于:https://w…

QT的常用对话框的应用

QMessageBox类提供了常用的弹出式对话框&#xff1a;提示、警告、错误、询问、关于对话框 需要添加头文件 #include <QMessageBox> MESSAGE 是要是显示的字符串 void Dialog::criticalMessage() { QMessageBox::StandardButton reply; reply QMessageBox::critical…

【spider】Tesseract机器视觉实现验证码识别

本文将重点介绍机器视觉的一个分支&#xff1a;文字识别&#xff0c; 介绍如何用一些 Python库来识别和使用在线图片中的文字 我们可以很轻松的阅读图片里的文字&#xff0c;但是机器阅读这些图片就会非常困难&#xff0c;利用这种人类用户可以正常读取但是大多数机器人都没法…

初识MVC

好多次听见别人说MVC&#xff0c;那么MVC到底是什么呢&#xff1f;今天来一探到底&#xff0c;揭开其神奇面纱。。 MVC介绍&#xff1a; MVC全名Model View Controller&#xff0c;是模型&#xff08;Model&#xff09;-视图&#xff08;View&#xff09;-控制器&#xff08;Co…

【spider】selenium模拟点击斗鱼示例

from selenium import webdriver import timeurl https://www.douyu.com/directory/all# 动态html网页加载可能出现的问题&#xff1a;element is not attached to the page document # 标签没有及时的加载显示出来&#xff0c;如果加载时间不够&#xff0c;可能报错 # try e…

webpack简介

webpack是 前端资源模块化管理工具和打包工具&#xff1b;webpack本身只能识别模块引入&#xff0c;打包模块的功能&#xff1b;webpack能识别ES Moudule、common JS等模块规范一、现有模块系统1、CommonJS关键词&#xff1a;module.exports exports require特点&#xf…

【Python + Selenium】之JS定位总结

1、滚动条 driver.set_window_size(500,500) js "window.scrollTo(0,200)" #左&#xff1a;距左边横滚、右&#xff1a;距上边竖滚 driver.execute_script(js) 2、获取元素的值 button driver.find_element_by_css_selector("#su") #定位按钮 input…

BigDecimal类整除报错的解决方案

例如&#xff1a; BigDecimal num1 new BigDecimal("10"); BigDecimal num2 new BigDecimal("3"); BigDecimal num3 num1.divide(num2); 其实devide的函数定义如下 BigDecimal.divide(BigDecimal divisor, int scale, RoundingMode roundingMode) ;…

NodeJS中的require和import

ES6标准发布后&#xff0c;module成为标准&#xff0c;标准的使用是以export指令导出接口&#xff0c;以import引入模块&#xff0c;但是在我们一贯的node模块中&#xff0c;我们采用的是CommonJS规范&#xff0c;使用require引入模块&#xff0c;使用module.exports导出接口。…

【selenium】selenium和requests登陆的区别

requests登陆 import requests import time t int(time.time()*1000) # 创建一个会话 s requests.Session() post_url http://account.chinaunix.net/login/login data {username: xxxxxxxxx,password: xxxxxxxxx,_token: nmSXhgHib8dTIC9DrATSkTzBBo4zz9eqDEPeG5i1,_t: t…

【spider】多线程爬虫

多线程工作原理 多线程示意图 Queue&#xff08;队列对象&#xff09; queue是python中的标准库&#xff0c;可以直接from queue import Queue引用;队列是线程间最常用的交换数据的形式 python下多线程的思考 对于资源&#xff0c;加锁是个重要的环节。Queue&#xff0c;是线…

css设置文字上下居中,一行文字居中,两行或多行文字同样居中。

HTML: <div class"book-detail-store-item align-center-vertical">居中文字</div> CSS: .book-detail-store-item {width: 50px&#xff1b;height&#xff1a;50px&#xff1b;line-height: 25px;font-size: 12px;}/*flex垂直居中对齐*/ .align-center…