Java-Daemon mit systemd konfigurieren

Java-Daemon mit systemd konfigurieren

Ich verwende diese Definition für einen systemdJob:

 [Unit]
 Description=Some job

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

 [Install]
 WantedBy=multi-user.target

Das Skript wird wie folgt aufgerufen (Aufruf einer einfachen Routine, die auf einem TCP/IP-Socket lauscht und die Eingabe an eine Datei anhängt):

 #!/bin/sh

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

Nachdem systemctl start somejobder Prozess als ausgeführt angezeigt wird, mit initdem übergeordneten Prozess:

 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

Nach der Durchführung systemctl stop somejobwird der Vorgang nicht mehr angezeigt (und der Port ist geschlossen).

Also alles scheint in Ordnung zu sein

Meine Frage ist: Ist das einakzeptable Lösungzum Ausführen eines Java-Daemons mit systemd, oder gibt es Einschränkungen und daher andere stabilere oder sicherere Möglichkeiten, dies zu erreichen?

Antwort1

Hier sind einige kleinere Änderungen:

  1. Da es auf einem Netzwerk-Socket lauscht, machen Sie es zu einer Abhängigkeit von network.target.
  2. nohupist nicht erforderlich, da systemddie ausführbare Datei für Sie als Daemon ausgeführt wird.
  3. Ich denke, ein separates Shell-Skript wäre übertrieben, also integrieren Sie es einfach in die Servicedatei.
  4. Eine Umleitung ( < /dev/nullusw.) ist nicht erforderlich, da systemd einen geeigneten Standard-E/A-Kontext einrichtet. Tatsächlich, wenn Sie die Umleitung nehmenaussystemd protokolliert alles, was vom Java-Programm an die Standardausgabe gesendet wird, in seinem Journal. Dafür ist kein spezieller Protokollierungsmechanismus erforderlich.
  5. Eine asynchrone Ausführung von der aufrufenden Shell ( &) aus ist weder erforderlich noch sinnvoll.
  6. Es gibt ein bestimmtes Verhaltensmuster, das von verlangt wird Type=forking, und wenn der Dæmon es nicht befolgt, geht etwas schief. Versuchen Sie es also mit Type=simple(oder Type=notify).

Die Servicedatei sieht also folgendermaßen aus:

[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

Anmerkungen:

  1. Sie können nicht einfach javaals Namen des auszuführenden Programms verwenden. systemd sucht nicht PATHnach ausführbaren Dateien und der Name der angegebenen ausführbaren Datei ExecStartmuss absolut sein. Wenn Sie also eine Pfadsuche wünschen, müssen Sie über eine Shell oder aufrufen /usr/bin/env. Wir wählen /bin/shhier.
  2. Da es sich hierbei um Type=simpleeine Shell exechandelt, muss diese in Java ausgeführt werden und darf nicht als untergeordneter Prozess ausgeführt werden. systemd steuert den Dienst über den Hauptprozess, und dieser muss in Java ausgeführt werden und darf kein übergeordneter Shell-Prozess sein.
  3. Da dies nicht direkt die Java-Programmdatei aufruft, trägt systemd den Namen shals Dienstnamen in sein Journal ein. SieheSo verhindern Sie, dass /usr/bin/env in Systemd-Protokollen als ausführbare Datei markiert wirdfür weitere Informationen.

Soweit ich weiß, gibt es keine besonderen Einschränkungen beim Ausführen von Java-Anwendungen mit Systemd.

verwandte Informationen