スポンサーリンク

Amazon EC2 デプロイ(CD/CI)

SpringBootをサービス化(デーモン化)して常駐させる

投稿日:2022年2月28日 更新日:

なぜ、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のエラー

基本的なトラブルシューティング

多くの場合、systemctl start 時にエラーが発生します。

その場合、systemctl status xxx -l でエラー内容を確認します。
それでもわからなければ、/var/log/messages を確認します。

/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 のユニットファイルの作り方

Udemyのハンズオン動画講座でSpringBootのスキルを磨く!

スポンサーリンク

-Amazon EC2, デプロイ(CD/CI)

Copyright© 【Spring Hack】 , 2022 All Rights Reserved Powered by AFFINGER5.