芹菜内码头容器内部



我的python应用程序中带有芹菜在docker容器中。我想要很少有不同队列的工人。例如:

celery worker -c 3 -Q queue1
celery worker -c 7 -Q queue2,queue3

,但我不在Docker组成的情况下这样做。我发现了有关芹菜多的关于芹菜的。我尝试使用它。

version: '3.2'
services:
  app:
    image: "app"
    build:
      context: .
    networks:
      - net
    ports:
      - 5004:5000
    stdin_open: true
    tty: true
    environment:
      FLASK_APP: app/app.py
      FLASK_DEBUG: 1
    volumes:
      - .:/home/app
  app__celery:
    image: "app"
    build:
      context: .
    command: sh -c 'celery multi start 2 -l INFO -c:1 3 -c:2 7 -Q:1 queue1 -Q:2 queue2,queue3'

但我明白了...

app__celery_1  |    > celery1@1ab37081acb9: OK
app__celery_1  |    > celery2@1ab37081acb9: OK
app__celery_1 exited with code 0

和带有芹菜的容器关闭。如何不让他关闭并从他那里获得原木?

upd:芹菜多创建的背景过程。如何在前景中开始芹菜多芹菜?

我完成了此任务。我使用了Substisord而不是芹菜多。主管从前景开始,我的容器未关闭。

command: supervisord -c supervisord.conf

,我将所有队列添加到subsevisord.con

[program:celery]
command = celery worker -A app.celery.celery -l INFO -c 3 -Q q1
directory = %(here)s
startsecs = 5
autostart = true
autorestart = true
stopwaitsecs = 300
stderr_logfile = /dev/stderr
stderr_logfile_maxbytes = 0
stdout_logfile = /dev/stdout
stdout_logfile_maxbytes = 0
[program:beat]
command = celery -A app.celery.celery beat -l INFO --pidfile=/tmp/beat.pid
directory = %(here)s
startsecs = 5
autostart = true
autorestart = true
stopwaitsecs = 300
stderr_logfile = /dev/stderr
stderr_logfile_maxbytes = 0
stdout_logfile = /dev/stdout
stdout_logfile_maxbytes = 0
[supervisord]
loglevel = info
nodaemon = true
pidfile = /tmp/supervisord.pid
logfile = /dev/null
logfile_maxbytes = 0

根据您的应用程序需求和设计,您实际上可能希望将工人在不同的容器中分开以完成不同任务。

但是,如果资源使用较低,并且将多个工人组合在一个容器中是有意义的,则可以通过入门点脚本进行。

编辑2019-12-05 :运行一段时间后。这不是生产使用的好主意。2个警告:

  1. 有背景工人默默退出但没有在前景中捕获的风险。tail -f将继续运行,但Docker不会知道背景工人停止了。根据您的芹菜调试级别设置,日志可能会显示一些指示,但是当您进行docker ps时,docker不知道。为了可靠,工人需要重新启动失败,这使我们提出了使用supervisord的建议。

  2. 在启动并停止(但未删除(码头容器状态时,保留了容器。这意味着,如果您的芹菜工人确实依靠pidfile进行身份证明,但是有一个令人难以置信的关闭,则有可能保留pidfile,并且工人也不会干净地重新启动docker stop; docker start。这是由于芹菜启动检测到以前的不干净关闭中剩余的pidfile的存在。为了防止多个实例,重新开始的工人以"发现的pidfile,芹菜已经在运行?"来阻止自己。必须使用docker rmdocker-compose down; docker-compose up卸下整个容器。处理此问题的几种方法:

    a。容器必须是run带有--rm标志的 CC_7,以卸下容器。

    b。也许不包括celery multi中的--pidfile参数或celery worker命令会更好。

摘要建议:最好使用supervisord

现在,详细信息:

Docker容器需要一个前景任务,或者容器将退出。这将进一步解决。

此外,芹菜工人可能会执行长期运行的任务,并且需要响应Docker的关闭(Sigterm(信号以优雅地关闭,即在关闭或重新启动之前完成长期运行的任务。

要实现Docker信号传播和处理,最好在Docker's exec 表单中声明entrypoint,您也可以在docker-compose文件

中执行此操作。

此外,由于芹菜多工具在后台工作,因此docker看不到任何日志。您需要能够显示前景中的日志,以使docker logs能够查看发生了什么。我们将通过为芹菜多工人设置logfile来做到这一点,并用tail -f <logfile_pattern>在控制台前显示。

我们需要实现三个目标:

  1. 使用前景任务运行Docker容器
  2. 接收,trap,然后处理Docker关闭信号
  3. 关闭工人优雅

对于#1,我们将运行tail -f &,然后在其上作为前景任务。

对于#2,这是通过设置trap函数并捕获信号来实现的。要通过陷阱功能接收和处理信号,wait必须是运行的前景任务,在#1中实现。

对于#3,我们将在celery multi start中的启动期间运行celery multi stop <number_of_workers_in_start_command>和其他参数参数。

这是我写的要点,在这里复制:

#!/bin/sh
# safety switch, exit script if there's error. Full command of shortcut `set -e`
set -o errexit
# safety switch, uninitialized variables will stop script. Full command of shortcut `set -u`
set -o nounset
# tear down function
teardown()
{
    echo " Signal caught..."
    echo "Stopping celery multi gracefully..."
    # send shutdown signal to celery workser via `celery multi`
    # command must mirror some of `celery multi start` arguments
    celery -A config.celery_app multi stop 3 --pidfile=./celery-%n.pid --logfile=./celery-%n%I.log
    echo "Stopped celery multi..."
    echo "Stopping last waited process"
    kill -s TERM "$child" 2> /dev/null
    echo "Stopped last waited process. Exiting..."
    exit 1
}
# start 3 celery worker via `celery multi` with declared logfile for `tail -f`
celery -A config.celery_app multi start 3 -l INFO -Q:1 queue1 -Q:2 queue1 -Q:3 queue3,celery -c:1-2 1 
    --pidfile=./celery-%n.pid 
    --logfile=./celery-%n%I.log
# start trapping signals (docker sends `SIGTERM` for shudown)
trap teardown SIGINT SIGTERM
# tail all the logs continuously to console for `docker logs` to see
tail -f ./celery*.log &
# capture process id of `tail` for tear down
child=$!
# waits for `tail -f` indefinitely and allows external signals,
# including docker stop signals, to be captured by `trap`
wait "$child"

使用上面的代码作为入门点脚本文件的内容,并根据您的需求进行相应的修改。

exec 表格中的dockerfile或docker-compose文件中声明它:

ENTRYPOINT ["entrypoint_file"]

然后,芹菜工人可以在码头容器中运行,也可以优雅地停止。

首先,我不明白使用Multi&amp;Docker。如我所见,您希望每个工人在一个单独的容器中。这样,您就有灵活性和微服务环境。

如果您仍然想在同一容器中有多个工人,我可以建议通过将while true; do sleep 2; done添加到命令的末尾来保持容器的打开: celery multi start 2 -l INFO -c:1 3 -c:2 7 -Q:1 queue1 -Q:2 queue2,queue3 && while true; do sleep 2; done

或者,将其包裹在一个简短的脚本中:

#!/bin/bash
celery multi start 2 -l INFO -c:1 3 -c:2 7 -Q:1 queue1 -Q:2 queue2,queue3
while true; do sleep 2; done

相关内容

  • 没有找到相关文章