You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用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_BACKENDRESULT_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

火山引擎 最新活动