Django项目中Celery配置SQS Broker后任务执行异常求助
Django + Celery + SQS 任务卡在"Messages in flight"状态未执行问题排查
可能的原因及对应解决方案
1. 任务序列化/反序列化失败
Celery默认使用json序列化,但SQS对消息格式的解析比RabbitMQ更严格。如果任务包含JSON无法序列化的对象(如自定义类实例、未正确处理的datetime对象),Worker拿到消息后无法解析任务,会导致任务一直卡在飞行状态,既不执行也不确认。
解决步骤:
- 检查任务参数,确保仅使用JSON原生支持的类型(字符串、数字、列表、字典等)。
- 临时切换序列化方式为
pickle测试(注意生产环境使用pickle存在安全风险,仅用于排查):
在Django配置中添加:CELERY_TASK_SERIALIZER = 'pickle' CELERY_RESULT_SERIALIZER = 'pickle' CELERY_ACCEPT_CONTENT = ['pickle', 'json']
2. Celery与AWS SDK版本不兼容
Celery的SQS传输依赖boto3和botocore,版本不匹配会导致消息交互逻辑出错,Worker无法正确处理SQS消息。
解决步骤:
- 安装Celery官方推荐的兼容版本依赖,例如:
版本号可根据Celery官方文档调整。pip install celery==5.3.4 boto3==1.28.61 botocore==1.31.61
3. SQS可见性超时配置不合理
如果SQS的可见性超时设置过短,会导致任务未完成就被重新放回队列;但你的情况是消息一直处于飞行状态,更可能是Worker因任务无法启动未发送确认信号。可尝试显式设置更长的可见性超时:
解决步骤:
- 在Broker传输配置中添加可见性超时,确保时长大于任务最长预期执行时间:
CELERY_BROKER_TRANSPORT_OPTIONS = { "region": "eu-west-1", "queue_name_prefix": "celery-", "visibility_timeout": 3600, # 示例:1小时,按需调整 }
4. 任务注册不匹配
虽然RabbitMQ下正常,但SQS对任务名称的解析可能更严格,若Worker未正确发现任务,会导致无法匹配消息中的任务标识。
解决步骤:
- 启动Worker时开启info级日志,查看是否有
Received task的日志条目:celery -A my-app worker --loglevel=info - 确认任务文件命名为
tasks.py,且所在的Django app已添加到INSTALLED_APPS,确保autodiscover_tasks()能扫描到任务。
5. SQS消息格式解析错误
从日志看Worker已获取到消息Body,但可能Body解码或解析出错,导致无法提取任务信息。
解决步骤:
- 手动解码日志中的Body内容:先对Base64编码的Body进行解码,再JSON解析,检查是否包含合法的Celery任务结构(如
task字段、args/kwargs参数)。
内容的提问来源于stack exchange,提问作者koleror
相关产品推荐
相关产品推荐

