настроить Java-демон с помощью systemd

11

Я использую это определение для systemdработы:

 [Unit]
 Description=Some job

 [Service]
 ExecStart=/usr/local/sbin/somejob
 User=dlt
 Type=forking

 [Install]
 WantedBy=multi-user.target

Сценарий вызывается следующим образом (вызывая простую подпрограмму, которая прослушивает сокет tcpip и добавляет входные данные в файл):

 #!/bin/sh

 cd /home/user/tmp/testout
 nohup java -jar /home/user/programming/tests/java/core/SocketTest/SocketTest.jar </dev/null >/dev/null &

После того, как systemctl start somejobпроцесс показывает, что работает, с initего родителем:

 user@CANTANDO ~$ ps -u dlt eo pid,ppid,command
   PID  PPID COMMAND
  8718     1 java -jar /home/user/programming/tests/java/core/SocketTest/SocketTest.jar

После выполнения systemctl stop somejobпроцесс больше не отображается (и порт закрыт).

Так что все выглядит хорошо и модно

Мой вопрос: приемлемо ли это для запуска Java-демона systemdили есть предостережения и, следовательно, другие более стабильные или безопасные способы достижения этого?

плеть
источник

Ответы:

14

Вот некоторые незначительные модификации:

  1. Поскольку он прослушивает сетевой сокет, сделайте его зависимым от network.target.
  2. nohupне требуется, так как systemdбудет демонизировать исполняемый файл для вас.
  3. Я думаю, что отдельный сценарий оболочки будет излишним, так что просто объедините его в служебный файл.
  4. Перенаправление ( < /dev/nullи т. Д.) Не требуется, поскольку systemd устанавливает соответствующий стандартный контекст ввода-вывода. В самом деле, если вы берете перенаправление , systemd запишет все, что отправлено на стандартный вывод программой Java в своем журнале, без специального механизма протоколирования.
  5. Запуск асинхронно из вызывающей оболочки ( &) не нужен или не подходит.
  6. Существует определенный образец поведения, требуемый Type=forking, и если за ним не следует демон, то дела идут плохо. Так что попробуйте для Type=simple(или Type=notify).

Итак, сервисный файл выглядит так:

[Unit]
Description=Some job
After=network.target

[Service]
WorkingDirectory=/home/user/tmp/testout
SyslogIdentifier=SocketTest
ExecStart=/bin/sh -c "exec java -jar /home/user/programming/tests/java/core/SocketTest/SocketTest.jar"
User=dlt
Type=simple

[Install]
WantedBy=multi-user.target

Заметки:

  1. Вы не можете просто использовать javaв качестве имени программы для запуска. systemd не ищет PATHисполняемые файлы, а имя исполняемого файла ExecStartдолжно быть абсолютным. Так что если вы хотите поиск пути, вы должны вызывать через оболочку или /usr/bin/env. Мы выбираем /bin/shздесь.
  2. Потому что это Type=simpleоболочка должна execJava, а не запускать ее как дочерний процесс. systemd управляет сервисом через основной процесс, и это должна быть Java, а не родительская оболочка.
  3. Поскольку это не вызывает исполняемый файл Java напрямую, systemd поместит имя shв свой журнал в качестве имени службы. См. Как избежать / usr / bin / env, помеченной в журналах systemd как исполняемый файл, для получения дополнительной информации об этом.

Насколько я знаю, нет особого предостережения о запуске приложения Java с Systemd.

Юн-Чи Чен
источник
1
Это не сработает. Проблема 1: Это не оболочка; нет операторов перенаправления. Вы действительно не хотите этого перенаправления в любом случае. Проблема 2: ExecStart требует абсолютных путей. Проблема 3: unix.stackexchange.com/questions/229523
JdeBP
Хорошая голова. Я могу только решить проблему 1. Как вы решаете проблему с пробой 2,3?
Юн-Чи Чен
1
Смотрите ответ в редакции.
JdeBP
Я не думаю, что ш здесь необходим.
faho
Здравствуйте @ Yun-ChihChen, как вы остановите процесс. Как будет выглядеть ExecStrop? Я использую init.d вместе с pid-файлом, но это оказалось проще. Так что мне нужно было убедиться, что я знаю, как остановиться и т. Д. Спасибо
черный сенсей