【问题标题】:Celery (Redis) results backend not working芹菜(Redis)结果后端不工作
【发布时间】:2016-06-03 01:27:56
【问题描述】:

我有一个使用 Django 的 Web 应用程序,并且我正在使用 Celery 进行一些异步任务处理。

对于 Celery,我使用 Rabbitmq 作为代理,使用 Redis 作为结果后端。

Rabbitmq 和 Redis 在本地虚拟机上托管的同一个 Ubuntu 14.04 服务器上运行。

Celery worker 正在远程机器上运行 (Windows 10)(Django 服务器上没有运行任何 worker)。

我有三个问题(我认为它们以某种方式相关!)。

  1. 无论任务成功还是失败,任务都保持在“PENDING”状态。
  2. 任务失败时不会重试。尝试重试时出现此错误:

reject requeue=False: [WinError 10061] 无法建立连接 因为目标机器主动拒绝了它

  1. 结果后端似乎无法正常工作。

我也对我的设置感到困惑,我不知道这个问题可能来自哪里!

这是我目前的设置:

my_app/settings.py

# region Celery Settings
CELERY_CONCURRENCY = 1
CELERY_ACCEPT_CONTENT = ['json']
# CELERY_RESULT_BACKEND = 'redis://:C@pV@lue2016@cvc.ma:6379/0'
BROKER_URL = 'amqp://soufiaane:C@pV@lue2016@cvc.ma:5672/cvcHost'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TASK_SERIALIZER = 'json'
CELERY_ACKS_LATE = True
CELERYD_PREFETCH_MULTIPLIER = 1

CELERY_REDIS_HOST = 'cvc.ma'
CELERY_REDIS_PORT = 6379
CELERY_REDIS_DB = 0
CELERY_RESULT_BACKEND = 'redis'
CELERY_RESULT_PASSWORD = "C@pV@lue2016"
REDIS_CONNECT_RETRY = True

AMQP_SERVER = "cvc.ma"
AMQP_PORT = 5672
AMQP_USER = "soufiaane"
AMQP_PASSWORD = "C@pV@lue2016"
AMQP_VHOST = "/cvcHost"
CELERYD_HIJACK_ROOT_LOGGER = True
CELERY_HIJACK_ROOT_LOGGER = True
CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler'
# endregion

my_app/celery_settings.py

from __future__ import absolute_import
from django.conf import settings
from celery import Celery
import django
import os

# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'my_app.settings')
django.setup()
app = Celery('CapValue', broker='amqp://soufiaane:C@pV@lue2016@cvc.ma/cvcHost', backend='redis://:C@pV@lue2016@cvc.ma:6379/0')

# Using a string here means the worker will not have to
# pickle the object when using Windows.
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)


@app.task(bind=True)
def debug_task(self):
    print('Request: {0!r}'.format(self.request))

my_app__init__.py

from __future__ import absolute_import

# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.

from .celery_settings import app as celery_app

my_app\email\tasks.py

from __future__ import absolute_import
from my_app.celery_settings import app

# here i only define the task skeleton because i'm executing this task on remote workers !
@app.task(name='email_task', bind=True, max_retries=3, default_retry_delay=1)
def email_task(self, job, email):
    try:
        print("x")
    except Exception as exc:
        self.retry(exc=exc)

在工人方面,我有一个文件“tasks.py”,其中包含任务的实际实现:

工人\tasks.py

from __future__ import absolute_import
from celery.utils.log import get_task_logger
from celery import Celery


logger = get_task_logger(__name__)
app = Celery('CapValue', broker='amqp://soufiaane:C@pV@lue2016@cvc.ma/cvcHost', backend='redis://:C@pV@lue2016@cvc.ma:6379/0')

@app.task(name='email_task', bind=True, max_retries=3, default_retry_delay=1)
def email_task(self, job, email):
    try:
        """
        The actual implementation of the task
        """
    except Exception as exc:
        self.retry(exc=exc)

我注意到的是:

  • 当我将工作人员中的代理设置更改为错误密码时,出现无法连接到代理错误。
  • 当我将工作人员中的结果后端设置更改为错误密码时,它会像一切正常一样正常运行。

什么可能导致我出现这些问题?

编辑

在我的 Redis 服务器上,我已经启用了远程连接

/etc/redis/redis.conf

... 绑定 0.0.0.0 ...

【问题讨论】:

  • 看起来您的结果后端配置不正确。
  • @scytale 怎么样??
  • 因为这就是它的样子。尝试从 django 和 celery 服务器查询 redis。我不熟悉如何配置 django/celery - 您在 my_app/settings.pymy_app/celery_settings.py 中复制了 celery 配置,而您没有 celeryconfig.py(这在独立 celery 中很常见) - 是这是推荐的做事方式?您使用什么文档?
  • @scytale 1 - 来自我运行的 django 和 celery 工人机器:>>> import redis >>> pool = redis.ConnectionPool(host='cvc.ma', port=6379, db=0, password='C@pV@lue2016') >>> r = redis.Redis(connection_pool=pool) >>> r.set('foo', 'bar') >>>True 所以 redis 配置似乎很好。 2 - 只有在将一些设置从my_app/settings.py 复制到my_app/celery_settings.py 之后,我才设法让 Celery 工作人员和 django 服务器一起工作。
  • @scytale 我没有使用任何特定的文档,我只是想通过 Celery 官方文档来解决问题,在这里让应用程序按照我想要的方式运行。所以可能这不是推荐的做事方式,这就是我在这里发布这个的原因。

标签: python django redis celery django-celery


【解决方案1】:

我有一个设置,其中“单实例服务器”(开发和本地主机服务器)正在工作,但当 redis 服务器是另一台服务器时却没有。芹菜任务正常工作,但没有得到结果。尝试获取任务结果时出现以下错误:

Error 111 connecting to localhost:6379. Connection refused.

使它起作用的原因只是将该设置添加到 Django:

CELERY_RESULT_BACKEND = 'redis://10.10.10.10:6379/0'

似乎如果这个参数不存在,它会默认为 localhost 来获取任务的结果。

【讨论】:

  • 我看到了同样的错误,即使我的设置是这样的(我想使用redis)我得到[2018-02-27 13:18:18,494: ERROR/MainProcess] consumer: Cannot connect to amqp://guest:**@127.0.0.1:5672//: [Errno 111] Connection refused. Trying again in 28.00 seconds...
  • 我正在使用 docker & docker-compose,没有自定义防火墙或其他东西。同样,相同的结构在另一个项目中有效,但在当前无效。我错过了一点,但不接受@mrmuggles
  • 啊抱歉,它似乎仍在尝试连接到本地主机而不是远程服务器?此外,如果您使用 redis,您的配置文件中可能缺少其他设置,“CELERY_RESULT_BACKEND”是不够的。你还需要设置这个:BROKER_URL = 'redis://100.100.100.1000:6379/0'。同样在初始化应用程序时:app = Celery('blcorp', backend='redis')
  • 谢谢你的回答,现在已经解决了,但我不确定之前出了什么问题:)
【解决方案2】:

CELERY_STORE_ERRORS_EVEN_IF_IGNORED = True 添加到我的设置中为我解决了这个问题。

【讨论】:

    【解决方案3】:

    我的猜测是您的问题出在密码上。 您的密码中包含@,这可以解释为user:passhost 部分之间的分隔符。

    工作人员处于待处理状态,因为他们无法正确连接到代理。 来自 celery 的文档 http://docs.celeryproject.org/en/latest/userguide/tasks.html#pending

    待处理 任务正在等待执行或未知。任何未知的任务 ID 都暗示处于挂起状态。

    【讨论】:

    • 出于测试目的,我确实将密码更改为简单密码,但我仍会遇到同样的问题。如果工作人员无法连接到代理,那么我的任务如何处理?
    • 让我们做一些试验。请尝试从 Celery 实例中删除结果后端。尝试添加ignore_result = True。 docs.celeryproject.org/en/latest/userguide/…
    • 抱歉,Gal Ben David 我下班了。所以我确实尝试了 ignore_result = True 并删除了结果后端。工作人员表示结果被禁用,当我提交任务时尝试 task.state 时出现错误:AttributeError: 'DisabledBackend' object has no attribute '_get_task_meta_for'
    • 在这种情况下,“apply”方法将不起作用,因为它等待任务执行完成,并返回返回值,该值目前被禁用。无论如何,尝试使用“apply_async”执行此操作并检查任务是否已成功运行。如果是这样的话,很明显问题出在后端服务器上,我们可以从那一点开始,逐个隔离。
    • 我没有使用 apply 方法,我从一开始就使用 apply_async。
    猜你喜欢
    • 2021-11-26
    • 1970-01-01
    • 2012-06-13
    • 2016-08-29
    • 2019-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多