celery task


前言

讨论一个定时任务,一般而言,需要的功能如下:

  1. 封装成对象,独立执行;
  2. 对象有一些接口,便于了解它的状态;
  3. 定时调用;
  4. 行为控制,包括重试,成功/失败回调等;

下面分别介绍celery的这些功能实现。

1.task basic

celery的task基础类是tasks.Task()

1.1 bound tasks

绑定代表第一个参数默认是self

logger = get_task_logger(__name__)

@task(bind=True)
def add(self, x, y):
logger.info(self.request.id)

1.2 Task类继承

需要注意的是声明的位置,是在把方法修饰成Task类时声明。

@app.task(base=MyTask)
def add(x, y):
#raise KeyError
return x + y

1.3 names

每个task实例都有一个非重复的名字,譬如下例:

@app.task(name='tasks.mul')
def mul(x, y):

一般不必要使用这一功能,特别是在task方法放在单独的module中时,默认name就是module name+方法名(celery_tasks.mul)。

尽量不要把任务模块命名为tasks.py,命名为celery_1.py更好一些。

1.4 其它属性

Task.max_retries 最大重试次数

Task.default_retry_delay 默认重试等待时间。

Task.ignore_result 抛弃结果,意味着不能通过 AsyncResult查看结果。

2.task 自定义任务行为

文档:http://docs.celeryproject.org/en/latest/userguide/tasks.html#custom-task-classes

主要有四种,包括失败/成功/重试/完成

on_failure on_success on_retry after_return

# celery_tasks.py
class MyTask(Task):
def on_success(self, retval, task_id, args, kwargs):
print 'task done: {0}'.format(retval)
return super(MyTask, self).on_success(retval, task_id, args, kwargs) def on_failure(self, exc, task_id, args, kwargs, einfo):
print 'task fail, reason: {0}'.format(exc)
return super(MyTask, self).on_failure(exc, task_id, args, kwargs, einfo) @app.task(base=MyTask)
def add(x, y):
return x + y

2.1 retry

app.Task.retry() 是实现重试的方法。

# an example of using retry:
@app.task(bind=True)
def send_twitter_status(self, oauth, tweet):
try:
twitter = Twitter(oauth)
twitter.update_status(tweet)
except (Twitter.FailWhaleError, Twitter.LoginError) as exc:
raise self.retry(exc=exc)

可以指定重试间隔时间,默认为180秒,下面案例指定为1800秒。

@app.task(bind=True, default_retry_delay=30 * 60)  # retry in 30 minutes.
def add(self, x, y):

关于最大重试次数等参数是在task实例中指定。

3. 定时执行 periodic task

文档:http://docs.celeryproject.org/en/latest/userguide/periodic-tasks.html

celery beat is a scheduler。

默认的参数源自beat_schedule。

3.1 时区

调度器默认使用UTC时区,当然需要修改:

timezone = 'Europe/London'

或 app.conf.timezone = 'Europe/London'

3.2 entries

有两种添加定时任务的方式,装饰器和配置文件。

常用配置文件方式。

3.2.1 从配置文件中读取定时任务

celery_config.py # 配置文件

#!/usr/bin/env python
#coding:utf-8 """
celery configure """
#__author__ = 'sss' from __future__ import absolute_import
from celery.schedules import crontab
from datetime import timedelta # 使用redis存储任务队列及结果
broker_url = 'redis://:123@192.168.199.113:6379/0'
result_backend = 'redis://:123@192.168.199.113:6379/1' task_serializer = 'json'
result_serializer = 'json'
accept_content = ['json'] # 时区
timezone = 'Asia/Shanghai' # celery默认开启自己的日志
# False表示不关闭
worker_hijack_root_logger = False
# 存储结果过期时间,过期后自动删除
# 单位为秒
result_expires = 60 * 60 * 24 # 导入任务所在文件
imports = [
'celery_tasks',
] # 定时任务配置
beat_schedule = {
'test1': {
# 具体需要执行的函数
# 该函数必须要使用@app.task装饰
'task': 'celery_tasks.test1_run',
# 定时时间
# 每分钟执行一次,不能为小数
'schedule': crontab(minute='*/1'),
# 或者这么写,每小时执行一次
# "schedule": crontab(minute=0, hour="*/1")
# 执行的函数需要的参数
'args': ()
},
'test2': {
'task': 'celery_tasks.test2_run',
# 设置定时的时间,10秒一次
'schedule': timedelta(seconds=10),
'args': ()
}}

celery_workder.py # 主文件

from __future__ import absolute_import

# 拒绝隐式引入,如果celery.py和celery模块名字一样,避免冲突,需要加上这条语句
# 该代码中,名字是不一样的,最好也要不一样
# celery test -- worker from celery import Celery def create_worker():
# app = Celery('tasks', broker=di)
'''app = Celery('tasks',
#backend=di_backend,
broker=di_broker,
include=['celery_tasks'])
'''
app = Celery()
#app.conf.update(result_expires=3600,)
app.config_from_object('celery_config')
return app app = create_worker()

celery_tasks.py # task方法文件


from celery_worker import app
from celery.task import Task
import time # tasks.py
class MyTask(Task):
def on_success(self, retval, task_id, args, kwargs):
print('task done: {0}'.format(retval))
return super(MyTask, self).on_success(retval, task_id, args, kwargs) def on_failure(self, exc, task_id, args, kwargs, einfo):
print('task fail, reason: {0}'.format(exc))
return super(MyTask, self).on_failure(exc, task_id, args, kwargs, einfo) @app.task(base=MyTask)
def add(x, y):
#raise KeyError
print('wwww')
return x + y @app.task
def mul(x, y):
return x * y @app.task
def xsum(numbers):
return sum(numbers) @app.task
def test(arg):
print(arg) def test11():
time.sleep(1)
print('test11') # ....略

运行-发布任务

celery -A celery_worker beat

运行-执行任务

celery -A celery_worker -l info -P eventlet

3.2.2 装饰器添加任务-动态添加

在上一章节中给出的案例是在配置文件中写入参数beat_schedule;

有时这样不太方便,需要更灵活的添加定时任务;

def setup_periodic_tasks(sender, **kwargs):
# 每5s调用 test('hello')
sender.add_periodic_task(5.0, test.s('hello'), name='add every 5') # 每20s调用 test('world')
sender.add_periodic_task(10.0, test.s('world'), expires=7) # 每周一早上7:30 执行 test('Happy Mondays!')
sender.add_periodic_task(
crontab(hour=7, minute=30, day_of_week=1), # 可灵活修改
test.s('Happy Mondays!'),
) setup_periodic_tasks(app)
print('定时任务列表', app.conf.beat_schedule)

执行命令celery -A celery_test beat -l debug

可以比较一下定时任务列表的输出。

没有添加任务:

(vir_venv) E:\python\code_2>celery -A  celery_test  beat  -l  debug
定时任务列表 {}
celery beat v4.3.0 (rhubarb) is starting.

添加任务之后:

(vir_venv) E:\python\code_2>celery -A  celery_test  beat  -l  debug
定时任务列表 # 已格式化
{
"add every 5": {
"schedule": 5.0,
"task": "celery_tasks.test",
"args": [
"hello"
],
"kwargs": {},
"options": {}
},
"celery_tasks.test('world')": {
"schedule": 10.0,
"task": "celery_tasks.test",
"args": [
"world"
],
"kwargs": {},
"options": {
"expires": 7
}
},
"celery_tasks.test('Happy Mondays!')": {
"schedule": "",
"task": "celery_tasks.test",
"args": [
"HappyMondays!"
],
"kwargs": {},
"options": {}
}
}

相关启动命令:

celery -A celery_worker worker -l info -P eventlet --logfile=c.log

celery -A celery_test beat -l debug

4. celery相关命令

发布任务

celery -A celery_task beat

执行任务

celery -A celery_task worker -l info -P eventlet

后台启动celery worker进程

celery multi start work_1 -A appcelery

停止worker进程,如果无法停止,加上-A

celery multi stop WORKNAME

重启worker进程

celery multi restart WORKNAME

查看进程数

celery status -A celery_task

5. 指定时间格式

复杂的定时功能可以使用crontab功能,它跟linux自带的crontab所支持的格式是一样的,非常方便定制任务执行时间。

from celery.schedules import crontab

app.conf.beat_schedule = {
# Executes every Monday morning at 7:30 a.m.
'add-every-monday-morning': {
'task': 'tasks.add',
'schedule': crontab(hour=7, minute=30, day_of_week=1),
'args': (16, 16),
},
}

上面的案例是在每个周一的7:30执行tasks.add任务。

celery task - 2的更多相关文章

  1. 分布式任务队列 Celery —— Task对象

    转载至 JmilkFan_范桂飓:http://blog.csdn.net/jmilk  目录 目录 前文列表 前言 Task 的实例化 任务的名字 任务的绑定 任务的重试 任务的请求上下文 任务的继 ...

  2. celery task异步任务

    业务端后台:通过python manage运行 运行用例时,用python manage运行时会卡,影响效率 celery task 本身自己也是个服务,异步处理case 异步:小明去给我买个东西,我 ...

  3. Celery Task(定时任务)及参数

    celery beat 是一个调度器:它以常规的时间间隔开启任务,任务将会在集群中的可用节点上运行. 默认情况下,入口项是从 beat_schedule 设置中获取,但是自定义的存储也可以使用,例如在 ...

  4. Celery 源码解析三: Task 对象的实现

    Task 的实现在 Celery 中你会发现有两处,一处位于 celery/app/task.py,这是第一个:第二个位于 celery/task/base.py 中,这是第二个.他们之间是有关系的, ...

  5. celery 停止执行中 task

    目录 原因 解决过程 原因 因为最近项目需求中需要提供对异步执行任务终止的功能,所以在寻找停止celery task任务的方法.这种需求以前没有碰到过,所以,只能求助于百度和google,但是找遍了资 ...

  6. 分布式任务队列 Celery —— 深入 Task

    目录 目录 前文列表 前言 Task 的实例化 任务的名字 任务的绑定 任务的重试 任务的请求上下文 任务的继承 前文列表 分布式任务队列 Celery 分布式任务队列 Celery -- 详解工作流 ...

  7. [源码解析] 并行分布式任务队列 Celery 之 Task是什么

    [源码解析] 并行分布式任务队列 Celery 之 Task是什么 目录 [源码解析] 并行分布式任务队列 Celery 之 Task是什么 0x00 摘要 0x01 思考出发点 0x02 示例代码 ...

  8. celery kill task

    from celery.task.control import revokerevoke(task_id, terminate=True) https://stackoverflow.com/ques ...

  9. 异步任务队列Celery在Django中的使用

    前段时间在Django Web平台开发中,碰到一些请求执行的任务时间较长(几分钟),为了加快用户的响应时间,因此决定采用异步任务的方式在后台执行这些任务.在同事的指引下接触了Celery这个异步任务队 ...

随机推荐

  1. ReLU(inplace=True),这里的inplace=true的意思

    ReLU(inplace=True),这里的inplace=true的意思 待办 inplace=True means that it will modify the input directly, ...

  2. 广度优先搜索(Breadth First Search, BFS)

    广度优先搜索(Breadth First Search, BFS) BFS算法实现的一般思路为: // BFS void BFS(int s){ queue<int> q; // 定义一个 ...

  3. python中一行字符串太多写不下时怎么写

    ‘123456789‘ 见此博客    https://www.cnblogs.com/wanderingzj/p/5244451.html str1=('123 '455' '789') 这样的话, ...

  4. JS高级---总结apply和call方法的使用

    apply和call的使用方法 apply的使用语法   函数名字.apply(对象,[参数1,参数2,...]); 方法名字.apply(对象,[参数1,参数2,...]);   call的使用语法 ...

  5. 字节流和字符流的read方法

    字节流和字符流的read方法 public class Test { public void fileOutput() throws Exception { File file = new File( ...

  6. vue + elementui表单重置 resetFields问题(无法重置表单)

    问题: elementui在重置表单时,无法使用this.$refs['formRefVal'].resetFields()清空表单数据; elementui 设置rules后没有效果 解决方法: 1 ...

  7. MySQL数据库 | 数据库和数据表的基本操作

    第一篇博文,一个小小的纪念仪式^-^ 以下正文 一.数据库的基本操作 --数据库的操作 --连接数据库 mysql -uroot -p密码 mysql -uroot -pmysql --退出数据库 e ...

  8. Django_模型

    1. ORM 2. 简单使用 3. 外键 2.0以上的版本要这样写s_grade = models.ForeignKey(Grade,on_delete=models.CASCADE) 3. 修改表名 ...

  9. python 更换数据源

    1.Win+R打开cmd输入%HOMEPATH%打开自己的HOMEPATH路径文件夹 2.在此路径下建立一个文件夹pip, 里边放一个文件pip.ini内容如下: [global] timeout = ...

  10. 程序员必需知道的Chrome使用技巧(入门篇)

    浏览器版本 Chrome Canary 新增一些没有经过Google工程师的测试或使用的浏览器功能版本.Chrome Dev让大多数开发人员主要使用此版本来测试对浏览器的重大版本功能版本.Chrome ...