ImageKit 异步错误 - 无法解码消息体

1 投票
1 回答
1008 浏览
提问于 2025-04-18 01:31

我正在使用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后端(同步)代替AsyncCelery在生产服务器上运行得很好。所以我不明白为什么异步后端会给我以下的导入错误(从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,所以我希望这只是我犯的一个愚蠢错误。我的谷歌搜索能力也没能帮上忙。

1 个回答

3

正如我在上面的评论中提到的,这种情况通常是因为忘记重启工作进程。

这是使用Celery时常见的一个小陷阱。工作进程和你的网页服务器是分开的,所以它们各自加载了自己的代码版本。就像网页服务器一样,如果你对代码进行了修改,就需要重新加载,这样它才能看到这些变化。网页服务器与工作进程的沟通不是直接运行代码,而是通过消息代理传递序列化的消息,比如“调用函数do_something()”。然后,工作进程会读取这个消息——这就是关键所在——并调用它自己版本的do_something()。所以即使你重启了网页服务器(这样它就能使用新版本的代码),如果你忘记重启工作进程(它才是真正调用函数的),那么还是会调用旧版本的函数。换句话说,每次你对任务进行修改时,都需要重启工作进程。

你可能想看看自动重载选项,这对开发来说可能会省去一些麻烦。

撰写回答