使用SQS时Django Celery报错“No result backend is configured”求助
问题:使用SQS作为Celery Broker时出现"No result backend is configured"错误
注意:此问题并非"Celery: No Result Backend Configured?"的重复问题,因为当前使用的是SQS作为Broker。
遇到的错误
No result backend is configured. Please see the documentation for more information.
生产环境Celery配置
CELERY_BROKER_URL = 'sqs://%s:%s@' % ( urllib.parse.quote(env.str('TASK_QUEUE_USER_ID'), safe=''), urllib.parse.quote(env.str('TASK_QUEUE_USER_SECRET'), safe='')) BROKER_URL = CELERY_BROKER_URL CELERY_ENABLE_REMOTE_CONTROL = False CELERY_RESULT_BACKEND = None # Disabling the results backend RESULT_BACKEND = None # Disabling the results backend CELERY_ACCEPT_CONTENT = ['application/json'] CELERY_TASK_SERIALIZER = 'json' CELERY_RESULT_SERIALIZER = 'json' CELERY_DEFAULT_QUEUE = 'async_tasks' SQS_QUEUE_NAME = 'async_tasks' CELERY_ENABLE_REMOTE_CONTROL = False CELERY_SEND_EVENTS = False CELERY_BROKER_TRANSPORT_OPTIONS = { 'region': 'eu-west-2', 'polling_interval': 3, 'visibility_timeout': 3600, } CELERY_SEND_TASK_ERROR_EMAILS = True # # https://stackoverflow.com/questions/8048556/celery-with-amazon-sqs#8567665 # CELERY_BROKER_TRANSPORT = 'sqs' BROKER_TRANSPORT = 'sqs'
问题场景
通过命令行启动Celery Worker时可以正常连接SQS并轮询:
DJANGO_ENV=production celery -A async_tasks worker -l info
但执行测试命令调用任务时(测试代码如下),会触发上述错误:
DJANGO_ENV=production python manage.py check_async
测试代码:
from django.core.management.base import BaseCommand, CommandError import async_tasks.tasks as tasks class Command(BaseCommand): help = 'Check if infrastructure for async tasks has been setup correctly.' def handle(self, *args, **options): try: print('Sending async request.') t = tasks.add.apply_async((2, 4)) out = t.get(timeout=1) print(out) print(t.status) except Exception as e: print(e) raise CommandError('Error occured')
开发环境使用Redis时一切正常,请问有什么解决思路?
解决思路
我来给你拆解下问题的核心:你现在的配置里明确把CELERY_RESULT_BACKEND和RESULT_BACKEND都设为None,也就是完全禁用了结果后端,但你的测试代码里却调用了t.get()和t.status——这两个操作必须依赖结果后端才能工作。
SQS只是一个消息队列(Broker),它的作用是传递任务消息,本身并不存储任务的执行结果。当你禁用结果后端后,Celery没有地方去保存任务的返回值和状态信息,自然就会抛出这个错误。
你可以根据自己的需求选择两种解决方案:
- 如果不需要获取任务结果/状态:直接删除测试代码中的
t.get()和print(t.status)代码,只保留任务提交逻辑即可,这样就不会触发结果后端的检查。 - 如果需要获取任务结果/状态:必须配置一个合法的结果后端,比如Redis、Django数据库或者其他Celery支持的存储方案。举个例子,如果你用Redis,就把配置改成:
同时确保对应的结果后端服务正常运行。CELERY_RESULT_BACKEND = 'redis://your-redis-host:6379/0' RESULT_BACKEND = 'redis://your-redis-host:6379/0'
另外补充下:你开发环境用Redis正常,是因为当时你肯定配置了Redis作为结果后端,所以t.get()能正常获取结果;现在换成SQS但没配置结果后端,就出现了这个矛盾。
内容的提问来源于stack exchange,提问作者Dimitrios Mistriotis




