Contents
- 1 なぜ、SpringBootアプリをサービス化するのか?
- 2 SpringBootアプリをサービス化(デーモン化)して常駐させる手順
- 3 サービス化(デーモン化)するにはsystemctlを使用する
- 4 systemctlのエラー
- 4.1 基本的なトラブルシューティング
- 4.2 main process exited, code=exited, status=1/FAILURE
- 4.3 main process exited, code=exited, status=217/USER
- 4.4 Loaded: error (Reason: Invalid argument) Executable path is not absolute, ignoring: java -jar /var/hoge/hoge.jar
- 4.5 Failed to start xxx.service: The name org.freedesktop.PolicyKit1 was not provided by any .service files
- 5 参考URL
なぜ、SpringBootアプリをサービス化するのか?
EC2にターミナル接続して、java -jar xxx.jar でSpringBootアプリを起動したは良いのですが、接続を切断したらアプリも落ちてしまうと、Webアプリとして公開できません。
そこで必要になるのがSpringBootアプリをサービス化(デーモン化)して常駐させることです。
SpringBootアプリをサービス化(デーモン化)して常駐させる手順
手順の概要
公式サイトの2.2.2. Installation as a systemd Serviceの手順に従います。
SpringBootアプリをサービス化(デーモン化)して常駐させる手順は次の通りです。
- サービス定義ファイルを作成する。
- サービス定義ファイルを読み込む。
- サービスを常駐にする設定をする。
- サービスを起動するユーザーを作成する。
- サービスを起動する。
手順の詳細
この手順では、okozukaiというアプリのファットjarが、/var/okozukai/okozukai-system-0.0.1-SNAPSHOT.jar
ここにあるという前提で進めています。
- まず、下記のサービス定義ファイルを
/etc/systemd/system
に作成します。
[ec2-user@ip-172-31-3-48 ~]$ sudo vi /usr/lib/systemd/system/okozukai.service
[Unit]
Description=application to manage okozukai.
After=syslog.target
[Service]
User=okozukai
ExecStart=/bin/java -jar /var/okozukai/okozukai-system-0.0.1-SNAPSHOT.jar
Restart=always
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
ExecStartはjava -jar
ではなく、/bin/java -jar
のように、コマンドの絶対パスで始める必要があります。
- 次に、書いたサービス定義ファイルを読み込みます。
[ec2-user@ip-172-31-3-48 ~]$ sudo systemctl daemon-reload
(xxx.service を変更した後で、systemctl start xxx
をすると、Warning: xxx.service changed on disk. Run 'systemctl daemon-reload' to reload units.
とエラーになるため、リロードが必要です)
(このときに、エラーが表示されたら、.serviceの内容に何か誤りがあります。)
- 次に、サービスを常駐にする設定をします。
[ec2-user@ip-172-31-3-48 ~]$ sudo systemctl enable okozukai
Created symlink from /etc/systemd/system/multi-user.target.wants/okozukai.service to /usr/lib/systemd/system/okozukai.service.
- さて起動!の前に、実行ユーザーを作成しておく必要があります。
// 実行ユーザーを作成(.serviceのUserと一致させる)
[ec2-user@ip-172-31-3-48 ~]$ sudo useradd okozukai
// 権限の確認
[ec2-user@ip-172-31-3-48 ~]$ ls -l /var/okozukai/okozukai-system-0.0.1-SNAPSHOT.jar
-rwxr-xr-- 1 ec2-user ec2-user 25950813 3月 2 00:52 /var/okozukai/okozukai-system-0.0.1-SNAPSHOT.jar
権限の確認では、実行ユーザーが読み取りができればOKです。
上記では所有者はec2-userですが、okozukaiもrはついているので、実行できます。
- 最後に、サービスを起動します。
[ec2-user@ip-172-31-3-48 ~]$ sudo systemctl start okozukai
[ec2-user@ip-172-31-3-48 ~]$ sudo systemctl status okozukai
● okozukai.service - application to manage okozukai.
Loaded: loaded (/etc/systemd/system/okozukai.service; enabled; vendor preset: disabled)
Active: active (running) since 水 2022-03-02 00:11:27 UTC; 44min ago
Main PID: 2553 (java)
CGroup: /system.slice/okozukai.service
└─2553 /bin/java -jar /home/spring/okozukai-system-0.0.1-SNAPSHOT.jar
3月 02 00:11:39 ip-172-31-3-48.ap-northeast-1.compute.internal java[2553]: 2022-03-02 00:11:39.121 INFO 2553 --- [ main] org.apache.cat...0.56]
3月 02 00:11:39 ip-172-31-3-48.ap-northeast-1.compute.internal java[2553]: 2022-03-02 00:11:39.368 INFO 2553 --- [ main] o.a.c.c.C.[Tom...ntext
3月 02 00:11:39 ip-172-31-3-48.ap-northeast-1.compute.internal java[2553]: 2022-03-02 00:11:39.375 INFO 2553 --- [ main] w.s.c.ServletW...94 ms
3月 02 00:11:42 ip-172-31-3-48.ap-northeast-1.compute.internal java[2553]: 2022-03-02 00:11:42.889 INFO 2553 --- [ main] o.s.b.a.w.s.We...index
3月 02 00:11:43 ip-172-31-3-48.ap-northeast-1.compute.internal java[2553]: 2022-03-02 00:11:43.510 INFO 2553 --- [ main] o.s.b.w.embedd...th ''
3月 02 00:11:43 ip-172-31-3-48.ap-northeast-1.compute.internal java[2553]: 2022-03-02 00:11:43.554 INFO 2553 --- [ main] c.s.o.Okozukai....981)
3月 02 00:11:52 ip-172-31-3-48.ap-northeast-1.compute.internal java[2553]: 2022-03-02 00:11:52.823 INFO 2553 --- [nio-8080-exec-1] o.a.c.c.C.[Tom...vlet'
3月 02 00:11:52 ip-172-31-3-48.ap-northeast-1.compute.internal java[2553]: 2022-03-02 00:11:52.824 INFO 2553 --- [nio-8080-exec-1] o.s.web.servle...vlet'
3月 02 00:11:52 ip-172-31-3-48.ap-northeast-1.compute.internal java[2553]: 2022-03-02 00:11:52.828 INFO 2553 --- [nio-8080-exec-1] o.s.web.servle... 4 ms
3月 02 00:55:50 ip-172-31-3-48.ap-northeast-1.compute.internal systemd[1]: Current command vanished from the unit file, execution of the command l...umed.
Hint: Some lines were ellipsized, use -l to show in full.
Active: active (running)
と表示されていれば、起動できているはずなので、ブラウザで動作確認してください。
サービス化(デーモン化)するにはsystemctlを使用する
systemctlとは?
常駐しているソフトウェア(アプリケーション)をサービスとかデーモンと言います。
EC2のAmazonLinux2、RHEL7、CentOS7などはアプリのサービス化を実現するために、systemdというソフトウェアを使用します。
systemdではサービス化する1つ1つのアプリをUnitという単位で扱います。
(この記事では便宜上、サービスと書いています)
サービスをsystemctlコマンド
を使用して停止・起動します。
サービス定義ファイルの置き場所
サービス定義ファイルは、xxx.service
というファイル名で記述します。
サービス定義ファイルの置き場所は2箇所あります。
/usr/lib/systemd/system/ | パッケージが提供するサービスのファイルを配置する場所。 |
/etc/systemd/system/ | システム管理者(あなた)がサービスのファイルを配置する場所です。 自作のサービス定義ファイルはこちらに置きます。 |
systemctlコマンド一覧
systemctl list-units | サービス一覧を表示 |
systemctl start サービス名 | サービスを開始 |
systemctl status サービス名 | サービスの状態を表示 |
systemctl stop サービス名 | サービスを停止 |
systemctl daemon-reload | サービス定義ファイルをリロード |
systemctl cat サービス名 | サービス定義ファイルを表示 |
systemctlのエラー
基本的なトラブルシューティング
多くの場合、systemctl start 時にエラーが発生します。
その場合、systemctl status xxx -l
でエラー内容を確認します。
それでもわからなければ、/var/log/message
s を確認します。
/var/log/messages には、systemctl status では表示されない内容が出力されていることがあります。
main process exited, code=exited, status=1/FAILURE
原因:/var/log/messages に出力されていることがある。
Mar 2 00:25:44 ip-172-31-6-96 java: Error: Unable to access jarfile /var/okozukai/okozukai-system-0.0.1-SNAPSHOT.jar
Mar 2 00:25:44 ip-172-31-6-96 systemd: okozukai.service: main process exited, code=exited, status=1/FAILURE
上記の場合だと、Unable to access jarfile とある。
これは、実行ユーザーがjarfileを読み取る権限がなかった。chmod o+x jarfile
で読み取り権限を付与すれば実行できた。
main process exited, code=exited, status=217/USER
原因:実行ユーザーが存在しない。
[Service]
User=hoge
このように書いてるけど、hogeユーザーが存在しないと思われます。
対策:hogeユーザーを作成する。sudo useradd hoge
で。
Loaded: error (Reason: Invalid argument) Executable path is not absolute, ignoring: java -jar /var/hoge/hoge.jar
原因:実行コマンドのパスが絶対パスではない。
[Service]
ExecStart=java -jar /var/okozukai/okozukai-system-0.0.1-SNAPSHOT.jar
ExecStart=java とあるが、javaコマンドは絶対パスである必要がある。
[ec2-user@ip-172-31-6-96 ~]$ which java
/usr/bin/java
このようにコマンドの絶対パスを調べて、ExecStart=/usr/bin/java
と修正する。
Failed to start xxx.service: The name org.freedesktop.PolicyKit1 was not provided by any .service files
[ec2-user@ip-172-31-3-48 ~]$ systemctl start xxx
Failed to start okozukai.service: The name org.freedesktop.PolicyKit1 was not provided by any .service files
See system logs and 'systemctl status okozukai.service' for details.
[ec2-user@ip-172-31-3-48 ~]$ sudo systemctl start xxx
[ec2-user@ip-172-31-3-48 ~]$
sudo を付与すると実行できます。
参考URL
サービス定義ファイルの詳しい書き方はこちらが参考になります。
晴耕雨読:systemd のユニットファイルの作り方