【问题标题】:Supervisord does not send signal to all the processes simultaneouslySupervisord 不会同时向所有进程发送信号
【发布时间】:2021-06-22 13:16:35
【问题描述】:

我有一个运行主管守护进程的 docker 容器。每当 docker 容器收到 SIGTERM 时,我想优雅地关闭主管正在运行的所有进程。默认情况下,Supervisor 最初会发送一个 SIGTERM 并等待 10 秒。如果进程没有退出,它会给它一个 SIGKILL。我想给这些过程更多的时间。我在主管文档中找到了以下内容

stopwaitsecs

The number of seconds to wait for the OS to return a SIGCHLD to supervisord after the
program has been sent a stopsignal. If this number of seconds elapses before supervisord  
receives a SIGCHLD from the process, supervisord will attempt to kill it with a final SIGKILL.

我假设主管会同时向所有进程发送第一个信号。
但这并没有发生。我观察到的行为是它向其中一个进程发送 SIGTERM,直到它被杀死(在 stopwaitsecs 之后),其他进程都没有收到第一个信号。

我正在使用的 dockerfile、supervisor 配置和程序如下。 Dockerfile


FROM ubuntu:18.04

RUN apt update -y
RUN apt upgrade -y

RUN apt-get install -y python3 python3-dev
RUN apt-get install -y python3-pip jq

RUN mkdir -p /opt/program/



WORKDIR "/opt/program/"
RUN apt-get install -y supervisor

ADD ./ /opt/program/
RUN cp /opt/program/collector_supervisor.conf /etc/supervisor/conf.d/
CMD  ["bash", "-c", " supervisord -c /opt/program/collector_supervisor.conf"]


主管的配置

[supervisord]
nodaemon=true

[program:prog1]
command=/usr/bin/python3 -u /opt/program/program.py
environment=PYTHONPATH=/opt/program/
stopwaitsecs=10
stderr_logfile=/dev/fd/1
stderr_logfile_maxbytes=0

[program:prog2]
command=/usr/bin/python3 -u /opt/program/program.py
environment=PYTHONPATH=/opt/program/
stopwaitsecs=10
stderr_logfile=/dev/fd/1
stderr_logfile_maxbytes=0

[program:prog3]
command=/usr/bin/python3 -u /opt/program/program.py
environment=PYTHONPATH=/opt/program/
stopwaitsecs=10
stderr_logfile=/dev/fd/1
stderr_logfile_maxbytes=0

程序.py

import logging
import time
import os
import sys
import signal

logging.basicConfig(level=logging.DEBUG)
def shutdown_handler(*args):
    logging.info("%s SIGTERM", os.getpid())
    for i in range(10):
        logging.info("Shutdown handler. Process %s, %s th second", os.getpid(), i)
        time.sleep(1)
    sys.exit()

signal.signal(signal.SIGTERM, shutdown_handler)

if __name__ == "__main__":
    while 1:
        time.sleep(1)
        logging.info("from process %s", os.getpid())

【问题讨论】:

  • 你能在三个独立的容器中运行三个进程,避免使用supervisord吗?删除 bash -c 包装器并使用 CMD 的 JSON 数组形式是否有帮助?
  • 感谢您的回答。但我希望所有进程都在同一个容器中。

标签: docker supervisord


【解决方案1】:

我要感谢this 线程上的用户kevinkreiser。以下是他的话。

我找到了一种解决方法,至少可以解决我没有同时发出关闭信号的问题,也许它也解决了关于启动/重新启动的 OP 问题,我还没有验证它。你可以做的是你可以在你的supervisord配置中使用分组(即[group:x])。我发现如果你这样做,信号确实会同时影响所有进程。

具体来说,如果您以我上面的示例并添加到配置的末尾:

[group:some_group_name]
programs=prog1,prog2,prog3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-21
    • 2017-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多