前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Celery用户手册 - Application

Celery用户手册 - Application

作者头像
用户1416054
发布2018-08-02 11:48:32
9250
发布2018-08-02 11:48:32
举报
文章被收录于专栏:JackeyGao的博客JackeyGao的博客

Celery用户手册 - Application

Posted April 18, 2016

Application

必须使用一个Application实例来创建celery 任务.

该Application线程是安全(thread-safe)的,以便你可以使用多个不同的Application 配置. 组件和任务能共存于相同的进程空间。

创建一个Application实例:

Python

代码语言:javascript
复制
>>> from celery import Celery
>>> app = Celery()
>>> app
<Celery __main__:0x100469fd0>

最后一行显示的是此Application实例的文本描述,其中包括celery类的名称,此实例存在于__main__ 主模块中和此实例的内存地址.

Main Name

Main Name 是个很重要的概念, 以下会介绍为什么重要.

当你使用Celery 推送一个任务消息, 这个消息不携带任何的源代码,但是需要指定一个此消息需要执行的任务名称。这种工作方式类似于hostname工作方式, 在网络上: 每个worker维护着任务名和他们所能执行的实际函数. 这就是所谓的task registry(任务注册表).

每当你定义一个任务, 该任务也将要添加到本地的task registry

Python

代码语言:javascript
复制
>>> @app.task
... def add(x, y):
...     return x + y
>>> add
<@task: __main__.add>
>>> add.name
__main__.add
>>> app.tasks['__main__.add'] # 根据task name取出实际函数(function)
<@task: __main__.add>

这里你会在此看到__main__ ,每当Celery无法检索到function属于哪个模块, 它会使用主模块名称生成任务模块, 即__main__.add.

这种现象只会出现在下面情况中:

  1. 定义的task所属的application 在一个主模块中
  2. 此application实例创建在Python 交互式环境中

第一种: tasks.py

Python

代码语言:javascript
复制
from celery import Celery
app = Celery()

@app.task
def add(x, y): return x + y

if __name__ == '__main__':
    app.worker_main()

当这个tasks.py 作为一个主模块执行的时候(__main__成立)任务名称以__main__开头, 即__main__.add. 但是当此模块被另外一个模块引用的时候,它的任务名称将以tasks开头, 即tasks.add.

Python

代码语言:javascript
复制
>>> from tasks import add
>>> add.name
tasks.add

可以在创建的Application的时候指定一个名称.

Python

代码语言:javascript
复制
>>> app = Celery('tasks')
>>> app.main
'tasks'

>>> @app.task
... def add(x, y):
...     return x + y

>>> add.name
tasks.add

参考: Names

Configuration

你可以设置Celery的其他选项,这些选项作用于application 实例. 但你最好单独定义一个配置模块。

查看一个配置

Python

代码语言:javascript
复制
>>> app.conf.CELERY_TIMEZONE
'Europe/London'

你也可以直接设置配置项

Python

代码语言:javascript
复制
>>> app.conf.CELERY_ENABLE_UTC = True

使用update方法更新多个键值.

Python

代码语言:javascript
复制
>>> app.conf.update(
...     CELERY_ENABLE_UTC=True,
...     CELERY_TIMEZONE='Europe/London',
...)

配置对象可以通过多种方法去修改操作, 他们的优先级是:

  1. 运行时修改
  2. 配置模块(如果有的话)
  3. 默认配置模块(celery.app.defaults)

你甚至可以使用celery.add_defaults()方法来添加新的默认源.

参见: Configuration reference 查看支持的通用选项参数列表.

configfromobject

Celery.config_from_object() 可以从一个配置对象加载配置, 可以是一个配置模块, 或者其他配置属性的对象.

需要注意的是, 使用此方法后默认参数将会被重置, 如果配置对象的键值和默认对象有冲突的话。 如果你想设置额外的配置你应该在之后在此方法之后去设置.

Example 1: 使用name作为module

Python

代码语言:javascript
复制
from celery import Celery

app = Celery()
app.config_from_object('celeryconfig')

celeryconfig 作为字符串对象传入, celeryconfig内容如下

celeryconfig.py: CELERY_ENABLE_UTC = True CELERY_TIMEZONE = 'Europe/London'

Example 2: 使用configtion module

Python

代码语言:javascript
复制
from celery import Celery

app = Celery()
import celeryconfig
app.config_from_object(celeryconfig)

Example 3: 使用configtion class/object

Python

代码语言:javascript
复制
from celery import Celery

app = Celery()

class Config:
    CELERY_ENABLE_UTC = True
    CELERY_TIMEZONE = 'Europe/London'

app.config_from_object(Config)
# or using the fully qualified name of the object:
#   app.config_from_object('module:Config')
configfromenvvar

使用Celery.config_from_envvar()方法可以从环境变量来设置选项.

从环境变量名为CELERYCONFIGMODULE加载配置:

Python

代码语言:javascript
复制
import os
from celery import Celery

#: Set default configuration module name
os.environ.setdefault('CELERY_CONFIG_MODULE', 'celeryconfig')

app = Celery()
app.config_from_envvar('CELERY_CONFIG_MODULE')

然后你可以指定配置模块,通过设置环境变量的方法:

Bash

代码语言:javascript
复制
$ CELERY_CONFIG_MODULE="celeryconfig.prod" celery worker -l info

Censored configuration

如果你想打印出配置, 但是你不想打印一些敏感的数据, 就像密码和API 密钥类似的敏感信息。

Celery 支持用于展示配置相关逻辑, 一个就是humanize():

Python

代码语言:javascript
复制
>>> app.conf.humanize(with_defaults=False, censored=True)

此方法将会隐藏敏感信息, 如果with_defaults为true的话, 可以显示为默认的值。

默认情况下Celery认为配置KEY中包含API, TOKEN, KEY, SECRET, PASS, SIGNATURE, DATABASE这些字符的都为敏感信息。

Breaking the chain

并没有看懂这段 , 貌似讲的是一种规范.

Abstract Tasks

以上所有的tasks创建的时候都使用了task() 装饰器,task会继承Task class.

当然可以指定成其他的Task基类, 比如下面代码中base=OtherTask, 那么此task的基类为OtherTask.

Python

代码语言:javascript
复制
@app.task(base=OtherTask):
def add(x, y):
    return x + y

如果你想创建一个自定义的Task 类, 你必须继承自celery.Task

Python

代码语言:javascript
复制
from celery import Task

class DebugTask(Task):
    abstract = True

    def __call__(self, *args, **kwargs):
        print('TASK STARTING: {0.name}[{0.request.id}]'.format(self))
        return super(DebugTask, self).__call__(*args, **kwargs)
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Celery用户手册 - Application
    • Application
      • Main Name
      • Configuration
      • Censored configuration
      • Breaking the chain
      • Abstract Tasks
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档