【问题标题】:Supervisord sometimes starts celery, sometimes notSupervisord 有时会启动 celery,有时不会
【发布时间】:2021-06-08 18:30:32
【问题描述】:

我正在 Kubernetes 上部署我的烧瓶 API。容器启动时执行的命令如下:

supervisord -c /etc/supervisor/conf.d/celery.conf 
gunicorn wsgi:app --bind=0.0.0.0:5000 --workers 1 --threads 12 --log-level=warning --access-logfile /var/log/gunicorn-access.log --error-logfile /var/log/gunicorn-error.log

您在上面看到,我首先使用主管启动 celery,然后运行 ​​gunicorn 服务器。 celery.conf 内容:

[supervisord]
logfile = /tmp/supervisord.log
logfile_maxbytes = 50MB
logfile_backups=10
loglevel = info
pidfile = /tmp/supervisord.pid
nodaemon = false
minfds = 1024
minprocs = 200
umask = 022
identifier = supervisor
directory = /tmp
nocleanup = true
[program:celery]
directory = /mydir/app
command = celery -A celery_worker.celery worker --loglevel=debug

登录到我的 pod 时,我可以看到有时启动 celery 的过程正在运行(例如在 pod 1 中):

> more /tmp/supervisord.log
2021-06-08 18:19:46,460 CRIT Supervisor running as root (no user in config file)
2021-06-08 18:19:46,462 INFO daemonizing the supervisord process
2021-06-08 18:19:46,462 INFO set current directory: '/tmp'
2021-06-08 18:19:46,463 INFO supervisord started with pid 9
2021-06-08 18:19:47,469 INFO spawned: 'celery' with pid 15
2021-06-08 18:19:48,470 INFO success: celery entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)

有时不是(在 pod 2 中):

> more /tmp/supervisord.log
2021-06-08 18:19:42,979 CRIT Supervisor running as root (no user in config file)
2021-06-08 18:19:42,988 INFO daemonizing the supervisord process
2021-06-08 18:19:42,988 INFO set current directory: '/tmp'
2021-06-08 18:19:42,989 INFO supervisord started with pid 9
2021-06-08 18:19:43,992 INFO spawned: 'celery' with pid 11
2021-06-08 18:19:44,994 INFO success: celery entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
>>>> 2021-06-08 18:19:58,642 INFO exited: celery (exit status 2; expected) <<<<<HERE

在我的 pod 1 中,ps 命令显示以下内容:

> ps aux | grep celery
root          9  0.0  0.0  55308 16376 ?        Ss   18:45   0:00 /usr/bin/python /usr/bin/supervisord -c         /etc/supervisor/conf.d/celery.conf
root         23  2.2  0.8 2343684 352940 ?      S    18:45   0:05 /usr/bin/python3 /usr/local/bin/celery -A celery_worker.celery worker --loglevel=debug
root         37  0.0  0.5 2341860 208716 ?      S    18:46   0:00 /usr/bin/python3 /usr/local/bin/celery -A celery_worker.celery worker --loglevel=debug
root         38  0.0  0.5 2341864 208716 ?      S    18:46   0:00 /usr/bin/python3 /usr/local/bin/celery -A celery_worker.celery worker --loglevel=debug
root         39  0.0  0.5 2341868 208716 ?      S    18:46   0:00 /usr/bin/python3 /usr/local/bin/celery -A celery_worker.celery worker --loglevel=debug
root         40  0.0  0.5 2341872 208724 ?      S    18:46   0:00 /usr/bin/python3 /usr/local/bin/celery -A celery_worker.celery worker --loglevel=debug
root         41  0.0  0.5 2341876 208728 ?      S    18:46   0:00 /usr/bin/python3 /usr/local/bin/celery -A celery_worker.celery worker --loglevel=debug
root         42  0.0  0.5 2341880 208728 ?      S    18:46   0:00 /usr/bin/python3 /usr/local/bin/celery -A celery_worker.celery worker --loglevel=debug
root         43  0.0  0.5 2341884 208736 ?      S    18:46   0:00 /usr/bin/python3 /usr/local/bin/celery -A celery_worker.celery worker --loglevel=debug
root         44  0.0  0.5 2342836 211384 ?      S    18:46   0:00 /usr/bin/python3 /usr/local/bin/celery -A celery_worker.celery worker --loglevel=debug    

在我的 pod 2 中,我可以看到 supervisord/celery 进程仍然存在,但我没有在 pod 1 中拥有的所有单独的 /usr/local/bin/celery 进程:

> ps aux | grep celery
root          9  0.0  0.0  55308 16296 ?        Ss   18:19   0:00 /usr/bin/python /usr/bin/supervisord -c /etc/supervisor/conf.d/celery.conf

这种行为并不总是相同的。有时当重新启动 pod 时,两者都成功启动了 celery,有时它们都没有成功。在最后一个场景中,如果我向我的 API 发出一个应该启动 celery 任务的请求,我可以在我的代理控制台 (RabbitMQ) 上看到一个任务已创建,但没有消息“活动”并且没有写入任何内容是我的数据库表(我的 celery 任务的最终结果)。

如果我在我的 pod 中手动启动 celery:

celery -A celery_worker.celery worker --loglevel=debug

一切正常。

什么可以解释这种行为?

【问题讨论】:

  • 一个更典型的最佳实践是在一个容器中只启动一个进程,而不用 supervisord。然后,您可以分别部署、升级和扩展 Web 服务器和 Celery 工作人员,并且可以使用 Kubernetes 的本机功能来监控和重新启动各个进程。
  • 你当然是对的,我一开始就想这样做。但我不确定这是否可能,因为 celery 需要我的应用程序才能启动。我认为它们必须在同一个 pod 上运行。也许我错了。
  • 您的应用容器中不需要 celery。是的,celery 将需要您的应用程序,但您可以使用完全相同的图像并在不同的容器中运行。只需更改入口点或 cmd 以运行 celery 而不是 gunicorn
  • 我现在就试一试。是否可以说 celery 容器不必是完全相同的图像,而只能包含使 ​​create_app 正常运行的严格最小值(当然还有 celery 任务)?
  • 我会这么认为,但我不能肯定地说。在我的使用中,我总是使用完全相同的图像。

标签: kubernetes celery supervisord


【解决方案1】:

按照上面的 cmets,最好的解决方案是拥有两个容器,第一个具有入口点 gunicorn,另一个具有 celery celery-worker。如果第二个镜像与第一个镜像相同,那么它工作得很好,我可以在 Kubernetes 上独立扩展每个容器。唯一的问题是代码采购更加困难,每次我在第一次进行代码更改时,我必须在第二次手动应用相同的更改,也许有更好的方法来解决代码采购的这个特定问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-15
    • 1970-01-01
    • 2017-08-19
    • 1970-01-01
    • 2011-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多