私は職場で次の定義を使用します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は適切な標準I / Oコンテキストを設定するので待つ必要はありません)。実際にリダイレクトすると出るsystemdは、特別なロギングメカニズムなしでJavaプログラムが標準出力に送信するすべての内容をログに記録します。 &
shell() 呼び出しで非同期的に実行することは、必要でも適切でもありません。- 特定の動作パターンが必要で
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
ファイル名はExecStart
絶対名でなければなりません。したがって、パスを検索したい場合は、シェルまたは経由で実行する必要があります/usr/bin/env
。/bin/sh
- これは
Type=simple
Javaシェルなので、子プロセスexec
として実行することはできません。 systemdは基本プロセスを介してサービスを制御します。これは親シェルプロセスではなくJavaである必要があります。 - これはJava実行可能ファイルへの直接呼び出しではないため、systemdはその名前を
sh
ログにサービス名に入れます。バラより/usr/bin/envがシステムログに実行可能ファイルとして表示されるのを防ぐ方法これについて詳しく学んでください。
私が知っている限り、Systemdを使用してJavaアプリケーションを実行すると特別な警告はありません。