systemd — дочерний элемент получает SIGTERM при выходе родителя

Окружающая среда:

У меня есть сервер Python, который разветвляется на 3 детей.

Для родителя:

  • Предполагается, что SIGTERM убивает всех детей, а SIGHUP просто должен регистрироваться и существовать.

Для ребенка:

  • И SIGTERM, и SIGHUP сопоставляются с SIG_DFL.

Проблема:

Когда я запускаю скрипт через командную строку python <script.py> и отправляю SIGHUP родительскому kill -1 <pid-of-parent>, он ведет себя хорошо. Родитель выходит, а занятые дети выходят только после завершения своих операций ввода-вывода.

Но если тот же сценарий запускается со сценарием systemd, когда я отправляю SIGHUP родителю, дочерние элементы, которые все еще заняты, получают SIGTERM, что приводит к нарушению ввода-вывода.

Любые объяснения/решения для этого? Это какая-то неправильная конфигурация?


person mittal    schedule 15.03.2016    source источник


Ответы (1)


Похоже, вам нужно установить KillMode для службы systemd на process.

KillMode ... Указывает, как процессы данного модуля должны быть уничтожены. ... Если установлено значение control-group, все оставшиеся процессы в группе управления этого устройства будут уничтожены при остановке устройства ... Если установлено значение process, уничтожается только сам основной процесс ... По умолчанию используется значение control-group

Дополнительная информация: https://www.freedesktop.org/software/systemd/man/systemd.kill.html#

Другой подход состоит в том, чтобы установить creationflags в subprocess.CREATE_NEW_PROCESS_GROUP в вызове subprocess.Popen, если вы порождаете процессы таким образом.

person Grief    schedule 15.03.2016
comment
Согласно документации KillMode будет действовать только в том случае, если служба остановлена ​​с помощью команды service stop. В моем случае я отправляю SIGHUP напрямую. Быстрый тест с использованием этого параметра также показывает то же самое. - person mittal; 15.03.2016
comment
Вы также можете попробовать установить SendSIGKILL=no - person Grief; 15.03.2016
comment
Я думаю, что все эти параметры будут иметь смысл только в том случае, если служба управляется с помощью одной сервисной команды. Если SIGHUP отправляется напрямую, они не будут учитываться. - person mittal; 15.03.2016
comment
Я бы попробовал сначала, если бы вы предоставили MCVE (stackoverflow.com/help/mcve), но, согласно вашему вопросу, нет различия, кроме запуска systemd, поэтому я предполагаю, что он убивает дочерние процессы. - person Grief; 15.03.2016
comment
Да, я пробовал это. После удаления большого количества пользовательского кода следующий скрипт запускает eventlet wsgi сервер pastebin.com/8TtN7KZ0. .service файл # cat /usr/lib/systemd/system/junk.service [Unit] Description=Junk service for testing purpose [Service] Type=simple ExecStart=/tmp/junk.py [Install] WantedBy=multi-user.target Примечание Для запуска сервера требуется пакет python-eventlet - person mittal; 18.03.2016
comment
Вот мой минимальный воспроизводимый пример :) Используя этот скрипт, вы можете понять, что я имел в виду. Если я запускаю службу с помощью service junk start, затем делаю kill -1 <pid-parent>, детей тоже убивают. Если вместо этого я сделаю python junk.py, а затем убью родительский процесс, дочерние процессы будут принадлежать 1(init), чего я и хочу. - person mittal; 19.03.2016
comment
@mittal: я уже ответил: вы должны добавить KillMode=process в раздел [Unit] service, почему вы даже не попробовали это? - person Grief; 19.03.2016
comment
Я попробовал, когда написал в своем первом комментарии «быстрый тест…». Но я попробую еще раз. Спасибо - person mittal; 21.03.2016
comment
После повторения тестов на моем реальном сервере приложений, похоже, он работает :) Все еще пытаюсь понять, почему он не работал раньше. Большое спасибо - person mittal; 21.03.2016