Celery 1
Celery是一个用Python开发的异步的分布式任务调度模块
Celery有以下优点:
- 简单:一但熟悉了celery的工作流程后,配置和使用还是比较简单的
- 高可用:当任务执行失败或执行过程中发生连接中断,celery 会自动尝试重新执行任务
- 快速:一个单进程的celery每分钟可处理上百万个任务
- 灵活: 几乎celery的各个组件都可以被扩展及自定制
应用:
创建tasks.py
from celery import Celery app = Celery('tasks', broker='amqp://guest@localhost//') @app.task def add(x, y): return x + y
Celery 的第一个参数是当前模块的名称,这个参数是必须的,这样的话名称可以自动生成。第二个参数是中间人关键字参数,指定你所使用的消息中间人的 URL,此处使用了 RabbitMQ,也是默认的选项
调用任务:
你可以用 delay()方法来调用任务
这是 apply_async() 方法的快捷方式,该方法允许你更好地控制任务执行
from tasks import add add.delay(4, 4)
保存结果:
如果你想要保持追踪任务的状态,Celery 需要在某个地方存储或发送这些状态。可以从内建的几个结果后端选择:SQLAlchemy/Django ORM、 Memcached 、 Redis 、 AMQP( RabbitMQ )或 MongoDB , 或者你可以自制。
下例中你将会使用 amqp 结果后端来发送状态消息。后端通过 Celery 的 backend 参数来指定。如果你选择使用配置模块,则通过 CELERY_RESULT_BACKEND 选项来设置:
app = Celery('tasks', backend='amqp', broker='amqp://')
配置:
Celery,如同家用电器一般,并不需要太多的操作。它有一个输入和一个输出, 你必须把输入连接到中间人上,如果想则把输出连接到结果后端上。但如果你仔细观察后盖,有一个盖子露出许多滑块、转盘和按钮:这就是配置。
默认配置对大多数使用案例已经足够好了,但有许多事情需要微调来让 Celery 如你所愿地工作。
配置可以直接在应用上设置,也可以使用一个独立的配置模块。
例如你可以通过修改 CELERY_TASK_SERIALIZER 选项来配置序列化任务载荷的默认的序列化方式:
app.conf.CELERY_TASK_SERIALIZER = 'json'
如果你一次性设置多个选项,你可以使用update:
app.conf.update( CELERY_TASK_SERIALIZER='json', CELERY_ACCEPT_CONTENT=['json'], # Ignore other content CELERY_RESULT_SERIALIZER='json', CELERY_TIMEZONE='Europe/Oslo', CELERY_ENABLE_UTC=True, )
对于大型项目,采用独立配置模块更为有效,事实上你会为硬编码周期任务间隔和任务路由选项感到沮丧,因为中心化保存配置更合适。尤其是对于库而言,这使得用户控制任务行为成为可能,你也可以想象系统管理员在遇到系统故障时对配置做出简单修改。
你可以调用 config_from_object() 来让 Celery 实例加载配置模块:
app.config_from_object('celeryconfig')
配置文件:celeryconfig.py
from kombu import Queue, Exchange BROKER_URL = 'redis://127.0.0.1:6379/7' CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/8' CELERY_IMPORTS = ( 'celery_app.task' ) CELERY_QUEUES = ( Queue('default', exchange=Exchange('default'), routing_key='default'), Queue('app_task1', exchange=Exchange('app_task1'), routing_key='app_task1'), Queue('app_task2', exchange=Exchange('app_task2'), routing_key='app_task2'), ) CELERY_ROUTES = { 'celery_app.task.task1': {'queue': 'app_task1', 'routing_key': 'app_task1'}, 'celery_app.task.task2': {'queue': 'app_task2', 'routing_key': 'app_task2'} }
定义routes用来决定不同的任务去哪一个queue
在启动worker时指定该worker执行哪一个queue中的任务
celery -A celery_app worker -l info -Q app_task1 -P eventlet celery -A celery_app worker -l info -Q app_task2 -P eventlet
RabbitMQ 是默认的中间人,所以除了需要你要使用的中间人实例的 URL 位置, 它并不需要任何额外的依赖或起始配置:
BROKER_URL = 'amqp://guest:guest@localhost:5672//'
如果想获取每个任务的执行结果,还需要配置一下把任务结果存在哪
app.conf.result_backend = 'redis://localhost:6379/0'
完整使用Celery流程
开始使用Celery啦
安装celery模块
pip install celery
创建一个celery application 用来定义你的任务列表
创建一个任务文件就叫tasks.py吧
from celery import Celery app = Celery('tasks', broker='redis://localhost', backend='redis://localhost') @app.task def add(x,y): print("running...",x,y) return x+y
启动Celery Worker来开始监听并执行任务
celery -A tasks worker --loglevel=info
调用任务
再打开一个终端, 进行命令行模式,调用任务
from tasks import add add.delay(4, 4)
看你的worker终端会显示收到 一个任务,此时你想看任务结果的话,需要在调用 任务时 赋值个变量
result = add.delay(4, 4)
结果
result.ready() # False or True
在项目中如何使用celery
可以把celery配置成一个应用
目录格式如下
proj/__init__.py /celery.py /tasks.py
proj/celery.py内容
from __future__ import absolute_import, unicode_literals from celery import Celery app = Celery('proj', broker='amqp://', backend='amqp://', include=['proj.tasks']) # Optional configuration, see the application user guide. app.conf.update( result_expires=3600, ) if __name__ == '__main__': app.start()
proj/tasks.py中的内容
from __future__ import absolute_import, unicode_literals from .celery import app @app.task def add(x, y): return x + y @app.task def mul(x, y): return x * y @app.task def xsum(numbers): return sum(numbers)
启动worker
celery -A proj worker -l info
Celery 定时任务
celery支持定时任务,设定好任务的执行时间,celery就会定时自动帮你执行, 这个定时任务模块叫celery beat
写一个脚本 叫periodic_task.py
from celery import Celery from celery.schedules import crontab app = Celery() @app.on_after_configure.connect def setup_periodic_tasks(sender, **kwargs): # Calls test('hello') every 10 seconds. sender.add_periodic_task(10.0, test.s('hello'), name='add every 10') # Calls test('world') every 30 seconds sender.add_periodic_task(30.0, test.s('world'), expires=10) # Executes every Monday morning at 7:30 a.m. sender.add_periodic_task( crontab(hour=7, minute=30, day_of_week=1), test.s('Happy Mondays!'), ) @app.task def test(arg): print(arg)
add_periodic_task 会添加一条定时任务
上面是通过调用函数添加定时任务,也可以像写配置文件 一样的形式添加, 下面是每30s执行的任务
app.conf.beat_schedule = { 'add-every-30-seconds': { 'task': 'tasks.add', 'schedule': 30.0, 'args': (16, 16) }, } app.conf.timezone = 'UTC'
任务添加好了,需要让celery单独启动一个进程来定时发起这些任务, 注意, 这里是发起任务,不是执行,这个进程只会不断的去检查你的任务计划, 每发现有任务需要执行了,就发起一个任务调用消息,交给celery worker去执行
启动任务调度器 celery beat
celery -A periodic_task beat
此时还差一步,就是还需要启动一个worker,负责执行celery beat发起的任务
启动celery worker来执行任务
celery -A periodic_task worker
此时观察worker的输出,是不是每隔一小会,就会执行一次定时任务呢!
celery -A periodic_task beat -s /home/celery/var/run/celerybeat-schedule
更复杂的定时配置
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), }, }
最佳实践之与django结合
Django项目目录:
- proj/ - proj/__init__.py - proj/settings.py - proj/urls.py - manage.py
创建文件proj/proj/celery.py
from __future__ import absolute_import, unicode_literals import os from celery import Celery # set the default Django settings module for the 'celery' program. os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proj.settings') app = Celery('proj') # Using a string here means the worker don'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))
配置proj/proj/__init__.py:
from __future__ import absolute_import, unicode_literals # This will make sure the app is always imported when # Django starts so that shared_task will use this app. from .celery import app as celery_app __all__ = ['celery_app']
为celery设置环境变量
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proj.settings')
创建Celery应用
app = Celery('proj')
配置settings
app.config_from_object('django.conf:settings', namespace='CELERY')
配置应用:
app.conf.update( # 配置broker, 这里我们用redis作为broker BROKER_URL='redis://:332572@127.0.0.1:6379/1', )
设置app自动加载任务:
app.autodiscover_tasks(settings.INSTALLED_APPS) # 从已经安装的app中查找任务
然后在具体的app里的tasks.py里写你的任务
# Create your tasks here from __future__ import absolute_import, unicode_literals from celery import shared_task @shared_task def add(x, y): return x + y @shared_task def mul(x, y): return x * y @shared_task def xsum(numbers): return sum(numbers)
在你的django views里调用celery task
from django.shortcuts import render,HttpResponse # Create your views here. from bernard import tasks def task_test(request): res = tasks.add.delay(228,24) print("start running task") print("async task res",res.get() ) return HttpResponse('res %s'%res.get())
注意,经测试,每添加或修改一个任务,celery beat都需要重启一次,要不然新的配置不会被celery beat进程读到
Celery 1的更多相关文章
- 异步任务队列Celery在Django中的使用
前段时间在Django Web平台开发中,碰到一些请求执行的任务时间较长(几分钟),为了加快用户的响应时间,因此决定采用异步任务的方式在后台执行这些任务.在同事的指引下接触了Celery这个异步任务队 ...
- celery使用的一些小坑和技巧(非从无到有的过程)
纯粹是记录一下自己在刚开始使用的时候遇到的一些坑,以及自己是怎样通过配合redis来解决问题的.文章分为三个部分,一是怎样跑起来,并且怎样监控相关的队列和任务:二是遇到的几个坑:三是给一些自己配合re ...
- tornado+sqlalchemy+celery,数据库连接消耗在哪里
随着公司业务的发展,网站的日活数也逐渐增多,以前只需要考虑将所需要的功能实现就行了,当日活越来越大的时候,就需要考虑对服务器的资源使用消耗情况有一个清楚的认知. 最近老是发现数据库的连接数如果 ...
- celery 框架
转自:http://www.cnblogs.com/forward-wang/p/5970806.html 生产者消费者模式 在实际的软件开发过程中,经常会碰到如下场景:某个模块负责产生数据,这些数据 ...
- celery使用方法
1.celery4.0以上不支持windows,用pip安装celery 2.启动redis-server.exe服务 3.编辑运行celery_blog2.py !/usr/bin/python c ...
- Celery的实践指南
http://www.cnblogs.com/ToDoToTry/p/5453149.html Celery的实践指南 Celery的实践指南 celery原理: celery实际上是实现了一个典 ...
- Using Celery with Djang
This document describes the current stable version of Celery (4.0). For development docs, go here. F ...
- centos6u3 安装 celery 总结
耗时大概6小时. 执行 pip install celery 之后, 在 mac 上 celery 可以正常运行, 在 centos 6u3 上报错如下: Traceback (most recent ...
- celery 异步任务小记
这里有一篇写的不错的:http://www.jianshu.com/p/1840035cb510 自己的"格式化"后的内容备忘下: 我们总在说c10k的问题, 也做了不少优化, 然 ...
- Celery 框架学习笔记
在学习Celery之前,我先简单的去了解了一下什么是生产者消费者模式. 生产者消费者模式 在实际的软件开发过程中,经常会碰到如下场景:某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是 ...
随机推荐
- note 6 函数
函数 完成特定功能的一个语句组,这组语句可以作为一个单位使用,并且给它取一个名字 通过函数名执行 数学 function(x) = x^2 - 2x + 1 abs(x) #求x的绝对值 定义函数 定 ...
- case class 和class的区别以及构造器参数辨析
工作中偶然发现Scala构造方法中的参数,无论是否有val/var修饰都可以顺利编译运行,如下: class AA(name: String) class BB(val name: String) 那 ...
- 傻瓜学编程之block_1
1.引出 1.1.int pp = 3;for循环为dd赋值并 调用 finprint(int ,int)函数 获取pp*dd的乘积,输出 void finalValue(int d, int sca ...
- C语言博客作业3--函数
C语言博客作业3--函数 1.本章学习总结 1.1思维导图 请以思维导图总结本周的学习内容,如下图所示: 1.2本章学习体会及代码量学习体会 1.2.1学习体会 描述本周学习感受,也可以在这里提出你不 ...
- Oracle根据主键获取对应表,Oracle根据外键获取相关表
Oracle根据主键获取对应表 select * from user_constraints a, USER_CONS_COLUMNS b where a.CONSTRAINT_TYPE = 'P' ...
- djangorestframework-jwt自带的认证视图进行用户登录验证源代码学习
Django REST framework JWT djangorestframework-jwt自带的认证视图进行用户登录验证源代码学习 SECRET_KEY = '1)q(f8jrz^edwtr2 ...
- TestNG 单元测试框架的使用
JUnit让开发人员了解测试的实用性,尤其是在单元测试这一模块上比任何其他测试框架都要简单明了.凭借一个相当简单,务实,严谨的架构,JUnit已经能够“感染”了一大批开发人员.TestNG是一个测试框 ...
- Django_tips
一.Django的配置静态文件(settings) STATIC_URL = '/static/' #引用名 STATICFILES_DIRS = ( os.path.join(BASE_DIR,&q ...
- PHP实现防止SQL注入的2种方法
PHP简单实现防止SQL注入的方法,结合实例形式分析了PHP防止SQL注入的常用操作技巧与注意事项,PHP源码备有详尽注释便于理解,需要的朋友可以参考下! 方法一:execute代入参数 $var_V ...
- [UNITY 5.4 UGUI] 控件重叠触摸穿透
问题. imge 和 button重叠时,imge 覆盖在button上面,导致点击事件无法传递到button. 1.给imge 添加 [Canvas Group]组件 2.修改[Canvas Gro ...