【问题标题】:Celery worker introspection to obtain hostname/nodenameCelery worker 自省获取主机名/节点名
【发布时间】:2015-09-30 14:05:07
【问题描述】:

我想为我的 Django 1.8 应用程序运行 py.test 集成测试 完整的 Celery 3.1 设置,即具有真实队列(不是 CELERY_ALWAYS_EAGER)。

为此,我需要说服工作人员使用我的基于服务器的测试数据库 (PostgreSQL) 而不是标准配置的数据库(SQlite3,它无法与第二个进程通信)。

为此,我想在首次使用数据库之前简单地修改工作进程中的DATABASES setting。 (我想保留 SQlite 用于其他 py.test 测试以及用于交互式测试的普通非测试数据库。)

为此,工作人员需要认识到它是在测试模式而不是“正常”模式下运行。 为了指示测试模式,我使用不同的节点名称启动工作程序:

celery worker -A myapp --concurrency=1 -n myworker --loglevel=info

普通模式对比

celery worker -A myapp --concurrency=1 -n mytestworker --loglevel=info

用于测试模式。

问题:我的 Django 应用程序中的 celery.py 模块如何读取 取出 worker 的节点名(主机名,使用 -n 选项设置)?

似乎涉及三个过程(我没有进一步的 上面的并发配置=1):

  1. celery.exe(我在 Windows 上),
  2. worker 本身,以及
  3. 单个工作进程(这对我来说是相关的)。

这对吗?

celery 向每个进程发送的signals 似乎不同:

  1. celeryd_init 发送到celery.exe
  2. worker_init 发送给worker
  3. worker_process_init 被发送到工作进程

这也是正确的吗?

我在我的 Django 应用程序中将以下内容添加到 celery.py

import celery.signals

def init_here(signal, sender):
    print("call %s(sender=%s)" % (signal, sender))

@celery.signals.celeryd_init.connect
def celeryd_init(sender, instance, **kwargs):
    init_here("celeryd_init", sender)

@celery.signals.worker_init.connect
def worker_init(sender, **kwargs):
    init_here("worker_init", sender)

@celery.signals.worker_process_init.connect
def worker_process_init(sender, **kwargs):
    init_here("worker_process_init", sender)

当我如上所述在测试模式下启动工作器时,我得到以下输出(除其他外):

call celeryd_init(sender=celery@mytestworker)
call worker_init(sender=celery@mytestworker)
[2015-09-30 15:53:23,767: WARNING/MainProcess] celery@mytestworker ready.
[2015-09-30 15:53:24,282: WARNING/Worker-1] call worker_process_init(sender=None)

太糟糕了!相关进程Worker-1没有收到相关信息celery@mytestworker。 如何获取主机名?

【问题讨论】:

  • 我的上述问题确实(如@Louis 所建议)最好由环境变量解决。但是,我仍然想知道所问问题的答案。

标签: python django celery


【解决方案1】:

即使你可以让它工作,我也不建议使用工人名称来检测你是否处于测试模式。这将是一个黑客攻击。

我解决知道我的代码是否在测试模式下运行的问题的方法是拥有一个名为proj/test_settings.py 的不同设置文件(而“常规”文件位于proj/settings.py),其中@ 987654323@ 是我的项目名称(与下面的PROJ 相同)。我让它创建一个设置来确定我们是否处于测试模式:

from .settings import *

PROJ_TESTING = True

此变量仅由 test_settings 文件设置为 true。请注意,在这个test_settings.py 文件中也可能有一些行覆盖settings.py 中设置的默认值。例如,我确实有代码可以更改数据库配置和日志记录。

我安排启动测试的代码设置环境变量DJANGO_SETTINGS_MODULE=proj.test_settings。由于我在测试中使用的 celery worker 是由运行我的测试的代码启动的,因此他们正在加载测试设置并以PROJ_TESTING true 运行。因此,如果需要检查测试模式,我可以这样做:

from django.conf import settings

if settings.PROJ_TESTING:
  # Do what we need when we are testing.
else:
  # Do something else.

这种处理方法反映了我们通过将DEBUG 设置为True 来设置调试模式的方式。

【讨论】:

    猜你喜欢
    • 2012-11-22
    • 2013-12-31
    • 1970-01-01
    • 1970-01-01
    • 2017-09-25
    • 1970-01-01
    • 2021-03-30
    • 2015-07-08
    • 2020-12-29
    相关资源
    最近更新 更多