
Я использую это определение для 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
или есть какие-то оговорки и, следовательно, другие более стабильные или безопасные способы достижения этой цели?
решение1
Вот некоторые незначительные изменения:
- Так как он прослушивает сетевой сокет, сделайте его зависимостью
network.target
. nohup
не требуется, так какsystemd
он демонизирует исполняемый файл.- Я думаю, что отдельный скрипт оболочки будет излишним, поэтому просто объедините его со служебным файлом.
- Перенаправление (
< /dev/null
и т. д.) не требуется, поскольку systemd устанавливает соответствующий стандартный контекст ввода-вывода. Действительно, если вы возьмете перенаправлениевнеsystemd будет регистрировать в своем журнале все, что отправляется на стандартный вывод программой Java, при этом не требуется никакого специального механизма регистрации. - Асинхронный запуск из вызывающей оболочки (
&
) не нужен и нецелесообразен. - Существует определенная модель поведения, требуемая
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
Примечания:
- Вы не можете просто использовать
java
в качестве имени программы для запуска. systemd не ищетPATH
исполняемые файлы, а имя исполняемого файла, указанное to,ExecStart
должно быть абсолютным. Поэтому, если вам нужен поиск пути, вам нужно вызвать через оболочку или/usr/bin/env
. Мы выбираем/bin/sh
здесь. - Поскольку это
Type=simple
оболочка, она должна бытьexec
Java, а не запускаться как дочерний процесс. systemd управляет службой через главный процесс, и это должна быть Java, а не родительский процесс оболочки. - Поскольку это не вызов исполняемого файла Java напрямую, systemd поместит имя
sh
в свой журнал как имя службы. СмотритеКак избежать маркировки /usr/bin/env в журналах systemd как исполняемого файладля получения более подробной информации об этом.
Насколько мне известно, никаких особых ограничений по запуску Java-приложений с помощью Systemd нет.