サービスが失敗したかsystemdがなぜ知らないのですか?

サービスが失敗したかsystemdがなぜ知らないのですか?

Ubuntu 18.04では、Spring Bootアプリケーション(他の人が開発しました - 私はJavaプログラマーではありません)を設定しようとしています。開発者は以前に/etc/init.dサービスを有効にするためにシンボリックリンクを追加しました。起動時に正常に起動しました。ただし、後でサービスが失敗した場合、systemdはサービスが実行中であることを報告します。

[email protected]:/var/log/apps# systemctl status crm-service
● crm-service.service - LSB: crm-service
   Loaded: loaded (/etc/init.d/crm-service; generated)
   Active: active (exited) since Wed 2020-04-15 12:27:15 BST; 3h 56min ago
     Docs: man:systemd-sysv-generator(8)
  Process: 8656 ExecStop=/etc/init.d/crm-service stop (code=exited, status=0/SUCCESS)
  Process: 8703 ExecStart=/etc/init.d/crm-service start (code=exited, status=0/SUCCESS)

Apr 15 12:27:15 example.com systemd[1]: Starting LSB: crm-service...
Apr 15 12:27:15 example.com crm-service[8703]: /var/services/crm-service.conf: line 1: -Xms96M: command not found
Apr 15 12:27:15 example.com crm-service[8703]: Started [8747]
Apr 15 12:27:15 example.com systemd[1]: Started LSB: crm-service.

私が見るとき同じシステム単位ファイルこの問題を解決できる springboot 関連のコンテンツがインターネットに公開されたことを見たことはありません。

  1. systemdにサービスの実際の状態を確認させる方法は? (リスニングソケットが開きますが、ランダムな高ポートで開きます)
  2. システム化して試してみる方法はありますか?やさしく失敗したことがわかっているサービスを再起動しますか?

答え1

Systemdには批評家があり、その多くは大丈夫ですが、そうではありません。Systemdは起動スクリプトから分岐(または複製)されたすべてのプロセスとスレッドを追跡でき、プロセスとスレッドが残っていない場合はサービスが中断されたと見なされます。

私が見た最初の問題は、systemdが起動/停止スクリプトを使用せずに/etc/init.d互換性プラグインにすぎないことです。代わりに、systemdはすべてのサービスの構成ファイルである単位ファイルを使用します。

systemd sysv init compatモジュールは、事実上/etc/init.dinitスクリプトに必要な情報が不足しているため(または情報を抽出できないため)、必ずしも可能ではありません。

compat モジュールがどのように機能するかは、終了コードが 0 でないと systemd が init スクリプトが失敗したとみなしてサービスが機能できないことです。 0 終了コードは成功した実行を意味します。初期化スクリプトにエラーがある場合は、systemdをだまして失敗してもゼロ終了コードを提供します。

初期化スクリプトエラーの最も可能性の高い原因は、バックグラウンドでプロセスを開始してから常にゼロで終了することです。カスタムプロバイダが書いたほとんどの初期化スクリプトの私の一般的な経験は、おそらくほとんど改善の余地があるということです。それらを信じないで、それらが何をするか見、修理しなさい。あなたの場合は、確認することをお勧めします。

  • Javaアプリケーションを起動する方法
  • どこから始めますか
  • どのユーザーが起動したか

ユニットファイルを使用して同じ機能を再現します。

Initscriptはsystemdで自動的に再起動することはできませんが、ユニットファイルでは自動的に再起動できます。

Javaプログラムがランダムに衝突しても、深刻な問題になります。すべての通常のJavaフレームワークは自分の致命的なエラーを正しく処理します(すべての例外をキャッチして記録し続けます)。

initスクリプトのもう1つの可能性が高いバグは、JVM(ほとんど:/usr/bin/java)が見つからないため、これを空の文字列に置き換えてJVMフラグをシェルで起動しようとすることです。コマンド。明らかに、-Xms96Mシステムにコマンドはありませんが、/usr/bin/java -Xms96M ...機能します。

Spring Bootアプリケーションのサンプル単位ファイル:

[Unit]
Description=Crm Spring Boot App Example
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/java -Xms96M ...other flags... your.spring.boot.jar
User=exampleuser
Group=examplegroup
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=exampleapp
WorkingDirectory=/path/to/app/home

[Install]
WantedBy=multi-user.target
Alias=exampleapp.service

また、ユニットファイルはJavaプロセスの標準出力とエラーをシステムログにリダイレクトします。

アプリケーションを自動的に再起動するには、次のように挿入します。

RestartSec=5s
Restart=on-failure

この[Service]セクションを入力してください。

体系的なチュートリアルがありますGoLinuxCloud.com

関連情報