【问题标题】:Celery: WorkerLostError: Worker exited prematurely: signal 9 (SIGKILL)芹菜:WorkerLostError:工人过早退出:信号9(SIGKILL)
【发布时间】:2014-05-13 08:38:31
【问题描述】:

我在我的 Django 应用程序(在 Elastic Beanstalk 上)中使用 Celery 和 RabbitMQ 来管理后台任务,并使用 Supervisor 对其进行守护。 现在的问题是,我定义的周期任务之一失败(在它正常工作一周后),我得到的错误是:

[01/Apr/2014 23:04:03] [ERROR] [celery.worker.job:272] Task clean-dead-sessions[1bfb5a0a-7914-4623-8b5b-35fc68443d2e] raised unexpected: WorkerLostError('Worker exited prematurely: signal 9 (SIGKILL).',)
Traceback (most recent call last):
  File "/opt/python/run/venv/lib/python2.7/site-packages/billiard/pool.py", line 1168, in mark_as_worker_lost
    human_status(exitcode)),
WorkerLostError: Worker exited prematurely: signal 9 (SIGKILL).

主管管理的所有进程都已启动并正常运行(supervisorctl status 表示 RUNNNING)。

我试图阅读我的 ec2 实例上的几份日志,但似乎没有人帮助我找出导致 SIGKILL 的原因。我该怎么办?我该如何调查?

这些是我的celery 设置

CELERY_TIMEZONE = 'UTC'
CELERY_TASK_SERIALIZER = 'json'
CELERY_ACCEPT_CONTENT = ['json']
BROKER_URL = os.environ['RABBITMQ_URL']
CELERY_IGNORE_RESULT = True
CELERY_DISABLE_RATE_LIMITS = False
CELERYD_HIJACK_ROOT_LOGGER = False

这是我的 supervisord.conf

[program:celery_worker]
environment=$env_variables
directory=/opt/python/current/app
command=/opt/python/run/venv/bin/celery worker -A com.cygora -l info --pidfile=/opt/python/run/celery_worker.pid
startsecs=10
stopwaitsecs=60
stopasgroup=true
killasgroup=true
autostart=true
autorestart=true
stdout_logfile=/opt/python/log/celery_worker.stdout.log
stdout_logfile_maxbytes=5MB
stdout_logfile_backups=10
stderr_logfile=/opt/python/log/celery_worker.stderr.log
stderr_logfile_maxbytes=5MB
stderr_logfile_backups=10
numprocs=1

[program:celery_beat]
environment=$env_variables
directory=/opt/python/current/app
command=/opt/python/run/venv/bin/celery beat -A com.cygora -l info --pidfile=/opt/python/run/celery_beat.pid --schedule=/opt/python/run/celery_beat_schedule
startsecs=10
stopwaitsecs=300
stopasgroup=true
killasgroup=true
autostart=false
autorestart=true
stdout_logfile=/opt/python/log/celery_beat.stdout.log
stdout_logfile_maxbytes=5MB
stdout_logfile_backups=10
stderr_logfile=/opt/python/log/celery_beat.stderr.log
stderr_logfile_maxbytes=5MB
stderr_logfile_backups=10
numprocs=1

编辑 1

重启celery beat后问题依旧。

编辑 2

killasgroup=true更改为killasgroup=false,问题依旧。

【问题讨论】:

  • 提示:很可能是因为您的服务器内存/内存不足。如果你通过 docker 命令运行容器,你可以使用docker stats查看每个容器的内存消耗。

标签: django amazon-ec2 celery amazon-elastic-beanstalk supervisord


【解决方案1】:

您的工作人员收到的 SIGKILL 是由另一个进程启动的。您的 supervisord 配置看起来不错,并且 killasgroup 只会影响主管启动的 kill(例如 ctl 或插件) - 如果没有该设置,它无论如何都会将信号发送给调度程序,而不是孩子。

您很可能发生了内存泄漏,并且操作系统的 oomkiller 正在暗杀您的进程的不良行为。

grep oom /var/log/messages。如果您看到消息,那就是您的问题。

如果您没有找到任何东西,请尝试在 shell 中手动运行周期性进程:

MyPeriodicTask().run()

然后看看会发生什么。如果您没有像仙人掌、神经节等这样的主机的良好仪器,我会在另一个终端中从顶部监控系统和进程指标。

【讨论】:

  • @daveoncode 我想刘易斯卡罗尔曾经写过,““当心 oom-killer,我的儿子!咬人的下巴,抓人的爪子!”
  • 在我的 Ubuntu 机器上,要检查的日志是 /var/log/kern.log,而不是 /var/log/messages
  • 在我的 Ubuntu 盒子里是/var/log/syslog(为了保持一致性)
  • @daveoncode 您是如何找到发生这种情况的原因的。我也停留在类似的位置。问题是它只发生在一项任务中,并且根据计算引擎,关于 cpu 使用和内存的一切似乎都很好
  • 我在 ecs 上运行 celery worker,每个任务的 RAM 太少,而且我还看到了 oom 杀死进程。所以它并不总是与内存泄漏有关,但也可能是 RAM 不足的原因。
【解决方案2】:

当您的异步任务(通过 celery)或您使用的脚本存储大量数据(在内存中)时,会引发这种错误。它会导致内存泄漏。

就我而言,我是从其他系统获取数据并将其保存在一个变量中,以便在完成整个过程后导出所有数据(到 Django 模型/Excel 文件中)。

这就是问题所在。我的脚本正在收集 1000 万个数据,当我将数据收集到我的 python 变量中时,它正在耗尽内存。这引发了错误。

为了解决这个问题,我将 1000 万个数据分成 20 个部分(每个部分 50 万个)。我检查过,当数据长度为 50 万时,我将数据存储到我自己喜欢的本地文件/Django 模型中。然后在接下来的 50 万美元中执行此操作,依此类推。

不需要精确的分区数。它是通过将复杂问题拆分为多个子问题并逐个解决子问题来解决复杂问题的想法。 :D

【讨论】:

    猜你喜欢
    • 2018-11-02
    • 2014-03-22
    • 2016-03-17
    • 1970-01-01
    • 2018-01-06
    • 1970-01-01
    • 1970-01-01
    • 2017-11-21
    • 2014-02-03
    相关资源
    最近更新 更多