Rhel 7: systemd не может запустить процесс, если указана опция фонового режима

Rhel 7: systemd не может запустить процесс, если указана опция фонового режима

У меня есть файл модуля systemd (serv_unit.service):

[Unit]
Description=My service

[Service]
Type=simple
Restart=always
RestartSec=60
StartLimitInterval=400
StartLimitBurst=3
ExecStart=/etc/init.d/myscript start

[Install]
WantedBy=multi-user.target

/etc/init.d/myscript

source /etc/myfile.sh # JAVA_home & other vars are resolved through this file
mode=$1
case "$mode" in
  'start')
    # Start daemon
    daemon --user=abc $JAVA_HOME/bin/java -cp $appClassPath $MAIN_CLASS $args &

Проблема, с которой я сталкиваюсь, возникает при запуске следующей команды:

systemctl start serv_unit.service

Я не вижу процесс Java. Но когда я удаляю завершающий&то есть:

daemon --user=abc $JAVA_HOME/bin/java -cp $appClassPath $MAIN_CLASS $args

можно увидеть процесс Java (и этот процесс Java не аварийно завершается, что исключает возможность его аварийного завершения в фоновом режиме)

В чем причина?

решение1

Помимо основного вопроса, вызов скриптов init.d из systemd немного избыточен и вообще плохая идея для начала. Вот все, что вам нужно:

User=abc
EnvironmentFile=/etc/myfile.conf
ExecStart=/usr/bin/env $JAVA_HOME/bin/java -cp $appClassPath $MAIN_CLASS $args

EnvironmentFile может содержать только простые назначения KEY=value, но если конфигурация должна быть представлена ​​в синтаксисе скрипта оболочки, вы также можете использовать:

User=abc
ExecStart=/bin/sh -c ". /etc/myfile.sh && exec $$JAVA_HOME/bin/java -cp $$appClassPath $$MAIN_CLASS $$args"

(В обоих случаях следует также установить SyslogIdentifier=, выдает ли служба сообщения stdout.)

Типы услуг

Ожидается, что службы Systemd будут следовать определенным правилам. У одного .serviceблока может быть только один «главный» процесс-демон, и эта Type=опция сообщает systemd, как работает этот процесс.

Type=simpleуказывает, что начальный процесс (т.е. то, что запущено из ExecStart=) сам по себе является основным процессом службы. Как только основной процесс завершается, служба считаетсяостановился, поэтому все остатки убираются.

Это означает, что если вы используете Type=simple, вы сообщаете systemd, что демонне будетперейти в 'фоновый'. Фактически, вы также сообщаете systemd, чтоскрипт init.d– нет daemon– это основной процесс сервиса...

Поэтому было бы лучше, если бы скрипт init.d не только не пытался перевести сам демон в фоновый режим, но и запускал его execследующим образом:

case "$mode" in
    'start-foreground')
        # Start daemon in foreground
        exec daemon --user=abc $JAVA_HOME/bin/java -cp $appClassPath $MAIN_CLASS $args

С другой стороны,Type=forkingуказывает на то, что первоначальный процессволяfork и выход во время процедуры запуска, а основной процесс должен быть обнаружен из PIDFile= или эвристически.

Какой из них использовать

С демонами, которые имеютвстроенныйРежим 'daemonize' Type=forkingимеет существенное преимущество: служба systemd остается в состоянии 'Starting' до тех пор, пока демон наконец не попытается перейти в фоновый режим, после чего он окончательно переходит в состояние 'Started/Active'. Это помогает при настройке зависимостей, например, служба A может объявить "After=B.service".

Но если фоновый режим выполняется внешними средствами, такими как &функция оболочки, без чего-либо, что могло бы сообщить, готов ли демон или нет, то это полностьюбесполезныйи вам, вероятно, следует просто использовать его Type=simpleбез каких-либо фоновых опций.

Связанный контент