我使用的是Django 1.6和Django-ImageKit 3.2.1。
我试图与ImageKit异步生成图像。异步映像生成在本地工作,但不在生产服务器上。
我使用Celery并且我已经尝试了两种方法:
IMAGEKIT_DEFAULT_CACHEFILE_BACKEND = 'imagekit.cachefiles.backends.Async'
IMAGEKIT_DEFAULT_CACHEFILE_BACKEND = 'imagekit.cachefiles.backends.Celery'
使用Simple
后端(同步)而不是Async
或Celery
在生产服务器上正常工作。所以我不明白异步后端为什么会给我以下ImportError(从Celery日志中提取):
[2014-04-05 21:51:26,325: CRITICAL/MainProcess] Can't decode message body: DecodeError(ImportError('No module named s3utils',),) [type:u'application/x-python-serialize' encoding:u'binary' headers:{}]
body: '\x80\x02}q\x01(U\x07expiresq\x02NU\x03utcq\x03\x88U\x04argsq\x04cimagekit.cachefiles.backends\nCelery\nq\x05)\x81q\x06}bcimagekit.cachefiles\nImageCacheFile\nq\x07)\x81q\x08}q\t(U\x11cachefile_backendq\nh\x06U\x12ca$
Traceback (most recent call last):
File "/opt/python/run/venv/lib/python2.6/site-packages/kombu/messaging.py", line 585, in _receive_callback
decoded = None if on_m else message.decode()
File "/opt/python/run/venv/lib/python2.6/site-packages/kombu/message.py", line 142, in decode
self.content_encoding, accept=self.accept)
File "/opt/python/run/venv/lib/python2.6/site-packages/kombu/serialization.py", line 184, in loads
return decode(data)
File "/usr/lib64/python2.6/contextlib.py", line 34, in __exit__
self.gen.throw(type, value, traceback)
File "/opt/python/run/venv/lib/python2.6/site-packages/kombu/serialization.py", line 59, in _reraise_errors
reraise(wrapper, wrapper(exc), sys.exc_info()[2])
File "/opt/python/run/venv/lib/python2.6/site-packages/kombu/serialization.py", line 55, in _reraise_errors
yield
File "/opt/python/run/venv/lib/python2.6/site-packages/kombu/serialization.py", line 184, in loads
return decode(data)
File "/opt/python/run/venv/lib/python2.6/site-packages/kombu/serialization.py", line 64, in pickle_loads
return load(BytesIO(s))
DecodeError: No module named s3utils
s3utils定义了我的AWS S3存储桶路径。如果需要,我会发布它,但我认为奇怪的是同步后端在异步执行时导入s3utils没有问题...并且异步仅在生产服务器上执行,而不是在本地执行。
我很乐意帮助调试这个。我好几天都在摔跤。我还在学习Django和python,所以我希望这对我来说是个愚蠢的错误。我的Google-fu让我失望了。
答案 0 :(得分:4)
正如我在上面的评论中暗示的那样,这种事情通常是由于忘记重新启动工作人员造成的。
这是芹菜的常见问题。工作者是与Web服务器分开的进程,因此他们有自己的代码版本加载。就像您的Web服务器一样,如果您对代码进行了更改,则需要重新加载以便它看到更改。 Web服务器不是通过直接运行代码,而是通过the broker传递序列化消息来与您的工作人员进行对话,这将说出类似于"调用函数do_something()
"。然后,工作人员将阅读该消息,并且 - 这是do_something()
的棘手部分调用其版本。因此,即使您重新启动Web服务器(以便它具有新版本的代码),如果您忘记重新加载工作程序(实际上是调用该函数),也会调用旧版本的函数。换句话说,您需要在任何时候更改任务时重新启动工作程序。
您可能需要查看the autoreload option以进行开发。它可以为你节省一些麻烦。