最近在Windows下用Celery的时候,碰到个问题:

1
app = Celery('tasks', backend = 'amqp', broker='amqp://guest@localhost//')

这样建立C对象后,backend的配置“未生效”——不能追溯任务的结果,但在启动的状态和检查status时又显示“生效了”,怪哉。
tasks.py如下

1
2
3
4
5
from celery import Celery
app = Celery('tasks', backend = 'amqp', broker='amqp://guest@localhost//')
@app.task
def add(x, y):
return x + y

启动界面如下:

1
2
3
4
5
6
7
8
9
10
11
12
-------------- celery@Lenovo-PC v3.1.18 (Cipater)
---- **** -----
--- * *** * -- Windows-8-6.2.9200
-- * - **** ---
- ** ---------- [config]
- ** ---------- .> app: tasks:0x34025f8
- ** ---------- .> transport: amqp://guest:**@localhost:5672//
- ** ---------- .> results: amqp
- *** --- * --- .> concurrency: 4 (prefork)
-- ******* ----
--- ***** ----- [queues]
-------------- .> celery exchange=celery(direct) key=celery

在python shell中做如下操作

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> res.backend
<celery.backends.amqp.AMQPBackend object at 0x000000000349E438>
>>> res = tasks.add.delay(2,2)
>>> res.ready()
False
>>> res.backend
<celery.backends.amqp.AMQPBackend object at 0x000000000349E438>
>>> res.ready()
False
>>> res.state
'PENDING'
>>> res.state
'PENDING'

不能获取到结果
通过尝试,在tasks.py中app创建后面加上
app.conf.CELERY_RESULT_BACKEND = ‘amqp’
手动配置BACKEND后,再次尝试,可以解决问题。

1
2
3
4
5
6
7
>>> res = tasks.add.delay(2,2)
>>> res.backend
<celery.backends.amqp.AMQPBackend object at 0x000000000349E438>
>>> res.get()
4
>>> res.ready()
True

但是问题的原因是啥,没搞懂,今天是国庆假期前一天,晚上没啥事,搜了一下,百度是没戏了,都是些互相抄的基础教程,试了下google,搜到这么一个页面,https://github.com/celery/celery/issues/897 里面的问题就是我的问题,看了一下,发现两个解决方法,一个和我的一样,一个是在celery启动的时候后面加–pool=solo,对比了一下发现加了–pool=solo后启动页面配置有变动:
Concurrency 分别是prefork和solo
查了Celery手册,
celery.concurrency.solo
Single-threaded pool implementation.
原文
celery.concurrency.prefork
Pool implementation using multiprocessing.
原文

综合一下所得信息:

  • 1,linux下没有问题,windows下才会出现
  • 2,单线程的时候backend可以获取到结果,多进程的时候获取不到
  • 3,多进程的时候可以通过app.conf.CELERY_RESULT_BACKEND配置,使得结果可以获取到
    感觉像是两种配置方法不同,受到多进程的影响了,结果没有顺利到达backend。