1. 序章

システムの観点から見たJavaアプリケーションは、Java仮想マシンの単なるインスタンスです。 この短いチュートリアルでは、アプリケーションをシステムサービスとして実行する方法を説明します。

systemdソフトウェアパッケージの機能を使用します。 systemdは、最新のLinuxディストリビューションの初期化およびサービス管理システムです。

チュートリアル全体を通して、2つの実装を検討します。1つは単純なケース用で、もう1つはより高度なケース用です。

2. シンプルなサービス

systemd の世界では、システムサービスを作成するには、ユニットファイルを準備して適切な方法で登録する必要があります。 ファイルの場所については後ほど説明しますが、最初にコンテンツから始めましょう。

[Unit]
Description=My Java driven simple service
After=syslog.target network.target

[Service]
SuccessExitStatus=143

User=appuser
Group=appgroup

Type=simple

Environment="JAVA_HOME=/path/to/jvmdir"
WorkingDirectory=/path/to/app/workdir
ExecStart=${JAVA_HOME}/bin/java -jar javaapp.jar
ExecStop=/bin/kill -15 $MAINPID

[Install]
WantedBy=multi-user.target

Typeのサービスをsimpleに設定しました。これは、システムが子プロセスを生成せずに、JVMプロセスを直接開始するためです。

ExecStop はサービス終了コマンドを指定し、systemdは開始されたプロセスのPIDを把握するのに十分賢いです。 MAINPID環境変数を自動的に作成します。

次に、 systemd に15(SIGTERM)システムシグナルを送信してプロセスを正常に終了するように指示します。

JVM設計者は、Javaがシステム信号によって終了した場合に、ゼロ以外の終了コードを返すようにしました。 ゼロ以外のベースとして、それらは128を取り、結果の終了コードは128とシグナル数値の合計になります。

SuccessExitStatusを143に設定することにより、systemdにその値(128 + 15)を通常のexitとして処理するように指示します。

3. フォークサービス

上記の単純なサービスユニットファイルは、簡単なアプリケーションには十分かもしれません。 ただし、より実用的なケースには、おそらく追加の設定が含まれます。

これらは、JVMパラメーターだけでなく、構成やデータファイルの場所などの他のアプリケーション固有のパラメーターでもかまいません。 その結果、JVMを起動する前に必要なすべてのパラメーターを設定できるラッパーシェルスクリプトが作成される可能性があります。

すでにラッパースクリプトがあり、それをシステムサービスに変換したいとします。

#!/bin/bash

JAVA_HOME=/path/to/jvmdir
WORKDIR=/path/to/app/workdir
JAVA_OPTIONS=" -Xms256m -Xmx512m -server "
APP_OPTIONS=" -c /path/to/app.config -d /path/to/datadir "

cd $WORKDIR
"${JAVA_HOME}/bin/java" $JAVA_OPTIONS -jar javaapp.jar $APP_OPTIONS

シェルスクリプトを使用してサービスを開始するため、JVMはシェル(bash)プロセスによって開始されます。この操作はフォークと呼ばれ、サービスを設定する理由です。 タイプからフォーク

変数定義をスクリプトの本文に移動すると、ユニットファイルもより簡潔になります。

[Unit]
Description=My Java forking service
After=syslog.target network.target
[Service]
SuccessExitStatus=143
User=appuser
Group=appgroup

Type=forking

ExecStart=/path/to/wrapper
ExecStop=/bin/kill -15 $MAINPID

[Install]
WantedBy=multi-user.target

4. サービスの登録と実行

どのサービスタイプを選択しても、ミッションを完了するには、システムサービス自体をセットアップして実行する方法を知っている必要があります。

まず、必要なサービス名にちなんでユニットファイルに名前を付ける必要があります。 この例では、javasimple.serviceまたはjavaforking.serviceのようになります。

次に、ユニットファイルをsystemdが検出できる場所の1つに配置します。 任意のサービスの場合、 / etc / systemd /systemが適切な選択です。

その場合、システムユニットへのフルパスは次のようになります。

  • /etc/systemd/system/javasimple.service
  • /etc/systemd/system/javaforking.service

システムユニットを配置するための別の可能なパスは、 / usr / lib / systemd /systemです。 これは通常、システムインストールパッケージで使用される場所です。

ただし、システムサービスを含む独自の.rpmまたは.debインストールパッケージを開発する場合は、より適切であると考える必要があります。

いずれの場合も、 systemctlユーティリティを使用してサービスを制御し、 start stop 、またはstatusコマンドのいずれかを渡します。

ただし、その前に、systemdに内部サービスデータベースを再構築する必要があることを通知する必要があります。 これを行うと、導入した新しいシステムユニットが認識されます。 これを行うには、daemon-reloadコマンドをsystemctlに渡します。

これで、前述のすべてのコマンドを実行する準備が整いました。

sudo systemctl daemon-reload

sudo systemctl start javasimple.service
sudo systemctl status javasimple.service
● javasimple.service - My Java driven simple service
Loaded: loaded (/etc/systemd/system/javasimple.service; <strong>disabled</strong>; vendor preset: disabled)
Active: active (running) since Sun 2021-01-17 20:10:19 CET; 8s ago
Main PID: 8124 (java)
CGroup: /system.slice/javasimple.service
└─8124 /path/to/jvmdir/bin/java -jar javaapp.jar

ユニットファイルを変更するたびに、daemon-reloadコマンドを実行する必要があります。

次に、システムがサービスの実行を報告しているが、が無効であることに気付きます。 無効になっているサービスは、システムの起動時に自動的に開始されません。

もちろん、システムと一緒に自動的に起動するように構成することもできます。 ここで、別の systemctl コマンドを使用します— enable

sudo systemctl enable javasimple.service
Created symlink from /etc/systemd/system/multi-user.target.wants/javasimple.service to /etc/systemd/system/javasimple.service

これで、有効になっていることがわかります。

sudo systemctl status javasimple.service
● javasimple.service - My Java driven simple service
Loaded: loaded (/etc/systemd/system/javasimple.service; <strong>enabled</strong>; vendor preset: disabled)
Active: active (running) since Sun 2021-01-17 20:10:19 CET; 14min ago
Main PID: 8124 (java)
....

5. 結論

この記事では、systemd。を使用してJavaアプリケーションをシステムサービスに変換する2つの方法について説明しました。

Javaは今でも最も人気のあるプログラミング言語の1つです。 多くのJavaアプリケーションは、データの処理、APIの提供、イベントの監視など、さまざまなタスクに対して非対話的に実行するように設計されています。 したがって、それらはすべてシステムサービスになるための良い候補です。