python Celery 基础
介绍
Celery 是一个 基于python开发的分布式异步消息任务队列,通过它可以轻松的实现任务的异步处理, 如果你的业务场景中需要用到异步任务,就可以考虑使用celery, 例子:
- 你想对100台机器执行一条批量命令,可能会花很长时间 ,但你不想让你的程序等着结果返回,而是给你返回 一个任务ID,你过一段时间只需要拿着这个任务id就可以拿到任务执行结果, 在任务执行ing进行时,你可以继续做其它的事情。
Celery 在执行任务时需要通过一个消息中间件来接收和发送任务消息,以及存储任务结果, 一般使用rabbitMQ or Redis,后面会讲
Celery有以下优点:
- 简单:一单熟悉了celery的工作流程后,配置和使用还是比较简单的
- 高可用:当任务执行失败或执行过程中发生连接中断,celery 会自动尝试重新执行任务
- 快速:一个单进程的celery每分钟可处理上百万个任务
- 灵活: 几乎celery的各个组件都可以被扩展及自定制
安装及基本使用
安装
pip3 install celery
pip3 install eventlet pip install -U "celery[redis]" #安装redis组件,使用redis做broker
配置
可以使用redis和rabbitmq做broker
#配置rabbitmq broker_url = 'amqp://guest:guest@localhost:5672//' #配置无密码redis app.conf.broker_url = 'redis://localhost:6379/0' #配置有密码redis app.conf.broker_url = redis://:password@hostname:port/db_number
#获取每个任务的执行结果,配置任务结果的存放位置 app.conf.result_backend = 'redis://localhost:6379/0'
简单使用测试
#cat test.py from celery import Celery app = Celery('tasks', broker='redis://10.10.10.11', backend='redis://10.10.10.11') @app.task def add(x, y): print("running...", x, y) return x + y
#启动Celery Worker来开始监听并执行任务 celery -A test worker --loglevel=info -P eventlet #这里的test为上面的test.py执行文件
新建终端执行命令
D:\django-project\wechat>python Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 18:41:36) [MSC v.1900 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> from test import add >>> add.delay(4, 4) <AsyncResult: c740d5fb-d7aa-4564-94b0-1e7258bbd23d> >>>
日志
[2018-05-15 16:39:36,845: INFO/MainProcess] Received task: test.add[c740d5fb-d7aa-4564-94b0-1e7258bbd23d] [2018-05-15 16:39:36,846: WARNING/MainProcess] running... [2018-05-15 16:39:36,847: WARNING/MainProcess] 4 [2018-05-15 16:39:36,847: WARNING/MainProcess] 4 [2018-05-15 16:39:36,883: INFO/MainProcess] Task test.add[c740d5fb-d7aa-4564-94b0-1e7258bbd23d] succeeded in 0.046000000002095476s: 8
如果报错
[2018-05-15 16:36:03,274: INFO/MainProcess] Received task: test.add[f2e6e1da-481f-45e4-a8db-3d1becd18b56] [2018-05-15 16:36:03,328: ERROR/MainProcess] Task handler raised error: ValueError('not enough values to unpack (expected 3, got 0)',) Traceback (most recent call last): File "c:\users\administrator\appdata\local\programs\python\python36\lib\site-packages\billiard\pool.py", line 358, in workloop result = (True, prepare_result(fun(*args, **kwargs))) File "c:\users\administrator\appdata\local\programs\python\python36\lib\site-packages\celery\app\trace.py", line 525, in _fast_trace_task tasks, accept, hostname = _loc ValueError: not enough values to unpack (expected 3, got 0)
解决办法
pip3 install eventlet
命令说明
result = func.delay("参数") result.ready() #表示查看函数是否执行完毕,是否返回结果 result.get(timeout=1) #设置超时时间
执行命令示例
from celery import Celery import subprocess app = Celery('tasks', broker='redis://10.10.10.11', backend='redis://10.10.10.11') @app.task def add(x, y): print("running...", x, y) return x + y @app.task def cmd_run(cmd): result = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) return result.stdout.read().decode("utf-8") #返回的结果为bytes类型,转换成str
启动
celery -A test worker --loglevel=info -P eventlet
打开终端执行
from test import cmd_run cmd_run.delay('ipconfig')
项目中使用celery
将celery配置成一个应用,目录结构如下
celery_proj/__init__.py #项目名称自己定义
/celery.py
/tasks.py
celery_proj/celery.py内容
from __future__ import absolute_import, unicode_literals from celery import Celery app = Celery('celery_proj', #这里proj为项目名称 broker='amqp://', #rabbitmq或redis地址 backend='amqp://', include=['proj.tasks']) app.conf.update( result_expires=3600, ) if __name__ == '__main__': app.start()
celery_proj/tasks.py中的内容
from __future__ import absolute_import, unicode_literals from .celery import app import subprocess @app.task def add(x, y): return x + y @app.task def mul(x, y): return x * y @app.task def cmd_run(cmd): result = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) return result.stdout.read().decode("utf-8")
启动
celery -A proj worker -l info -P eventlet #这里启动就要写项目名称了
日志
D:\django-project\wechat>celery -A celery_pro worker -l info -P eventlet -------------- celery@R201611161646 v4.1.0 (latentcall) ---- **** ----- --- * *** * -- Windows-7-6.1.7601-SP1 2018-05-16 10:47:55 -- * - **** --- - ** ---------- [config] - ** ---------- .> app: celery_pro:0x4635c50 - ** ---------- .> transport: redis://10.10.10.11:6379// - ** ---------- .> results: redis://10.10.10.11/ - *** --- * --- .> concurrency: 8 (eventlet) -- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker) --- ***** ----- -------------- [queues] .> celery exchange=celery(direct) key=celery [tasks] . celery_pro.test_celery.add . celery_pro.test_celery.cmd_run . celery_pro.test_celery.mul [2018-05-16 10:47:55,268: INFO/MainProcess] Connected to redis://10.10.10.11:6379// [2018-05-16 10:47:55,296: INFO/MainProcess] mingle: searching for neighbors [2018-05-16 10:47:56,455: INFO/MainProcess] mingle: all alone [2018-05-16 10:47:56,504: INFO/MainProcess] pidbox: Connected to redis://10.10.10.11:6379//. [2018-05-16 10:47:56,535: INFO/MainProcess] celery@R201611161646 ready. [2018-05-16 10:48:09,373: INFO/MainProcess] Received task: celery_pro.test_celery.cmd_run[fcfbe7e7-9ced-40b2-a231-d2f1f712a846] [2018-05-16 10:48:09,482: ERROR/MainProcess] Task celery_pro.test_celery.cmd_run[fcfbe7e7-9ced-40b2-a231-d2f1f712a846] raised unexpected: UnicodeDecodeError('utf-8', b' \xc7\xfd\xb6\ xaf\xc6\xf7 D \xd6\xd0\xb5\xc4\xbe\xed\xca\xc7 \xc8\xed\xbc\xfe\r\n \xbe\xed\xb5\xc4\xd0\xf2\xc1\xd0\xba\xc5\xca\xc7 0E89-3B03\r\n\r\n D:\\django-project\\wechat \xb5\xc4\xc4\xbf\xc2 \xbc\r\n\r\n2018/05/16 \xd6\xdc\xc8\xfd 10:37 <DIR> .\r\n2018/05/16 \xd6\xdc\xc8\xfd 10:37 <DIR> ..\r\n2018/05/16 \xd6\xdc\xc8\xfd 10:47 <DIR> .idea\r\n2018/05/16 \xd6\xdc\xc8\xfd 10:45 <DIR> celery_pro\r\n2018/05/10 \xd6\xdc\xcb\xc4 15:03 12,288 db.sqlite3\r\n2018/05/10 \xd6\xdc\xcb\xc4 11:37 249 manage.py\r\n2018/05/10 \xd6\xdc\xcb\xc4 14:17 <DIR> static\r\n2018/05/11 \xd6\xdc\xce\xe5 16:29 <DIR> templates\r\n2018/05/15 \xd6\xdc\xb6\xf e 17:41 1,216 test.py\r\n2018/05/11 \xd6\xdc\xce\xe5 16:29 <DIR> web\r\n2018/05/10 \xd6\xdc\xcb\xc4 16:45 <DIR> wechat\r\n2018/05/15 \xd6\xdc\x b6\xfe 17:43 <DIR> __pycache__\r\n 3 \xb8\xf6\xce\xc4\xbc\xfe 13,753 \xd7\xd6\xbd\xda\r\n 9 \xb8\xf6\xc4\xbf\xc2\xbc 226,018,455,552 \xbf\xc9\xd3\xc3\xd7\xd6\xbd\xda\r\n', 1, 2, 'invalid continuation byte')
后台启动
celery multi start w1 -A proj -l info #multi表示可启动多个 w1 表示自定义的启动名称 -A 项目名
celery multi restart/stop w1 -A proj -l info #重启/关闭

浙公网安备 33010602011771号