CentOS 7でsystemctlサービスが開始されなかった理由を知るにはどうすればよいですか?


12

CentOS 7を使用しています。サービスの開始に失敗する理由を知るにはどうすればよいですか?このサービスを作成しました

[rails@server ~]$ sudo cat /usr/lib/systemd/system/nodejs.service
[Unit]
Description=nodejs server

[Service]
User=rails
Group=rails
ExecStart=/home/rails/NodeJSserver/start.sh
ExecStop=/home/rails/NodeJSserver/stop.sh

[Install]
WantedBy=multi-user.target

ファイルはこれを指しています

[rails@server ~]$ cat /home/rails/NodeJSserver/start.sh
#!/bin/bash

forever start /home/rails/NodeJSserver/server.js

このファイルだけで問題なく実行できます。しかし、サービスの一部として実行しようとすると、nodeJSサーバーが起動していないことがわかります。「sudo systemctl --state = failed」をチェックしても、エラーは表示されません...

[rails@server ~]$ sudo systemctl enable NodeJSserver
[rails@server ~]$ sudo systemctl start NodeJSserver
[rails@server ~]$
[rails@server ~]$
[rails@server ~]$ forever list
info:    No forever processes running
[rails@server ~]$
[rails@server ~]$
[rails@server ~]$ sudo systemctl --state=failed
  UNIT                           LOAD   ACTIVE SUB    DESCRIPTION
● nginx.service                  loaded failed failed The nginx HTTP and reverse proxy server
● systemd-sysctl.service         loaded failed failed Apply Kernel Variables
● systemd-vconsole-setup.service loaded failed failed Setup Virtual Console

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

3 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.

サービスの開始に失敗した理由を知るにはどうすればよいですか?


journalctl -u nodejsより意味のあるエラーメッセージが表示されます。
フェデリコクレズカロカ

「ジャーナルファイルが見つかりませんでした。」というメッセージが表示されます。
Dave

sudo journalctlが動作するはずです。また、start.sh内で、出力ログファイルを別の場所にリダイレクトしているかどうかを確認します。
rogerdpack

回答:


13

セクションにサービスがType=指定されていない[Service]ため、systemdを意味していると想定していType=simpleます。

つまり、サービスが実行されている限り、systemd開始されたプロセスがExecStart=実行を継続することを期待します。しかし、start.sh1つのコマンドを実行して終了するようです。つまり、コマンド:背景に、デーモンとして、または他の言葉でtargetコマンドを開始します。コマンドが完了するとすぐに、実行中のシェルが終了します。foreverforever startforever startstart.sh

その時点で、systemdはこのサービスが失敗したと見なします。ただし、そのサービスに割り当てられたコントロールグループには、まだ実行中のプロセスがあります。「それで」と考えsystemd、「失敗しただけでなく、それ自体が混乱を残しました。それはあり得ません。」KillMode=KillSignal=指定もされていないためsystemd、デフォルトで続行し、その制御グループ内の残りのプロセスに対してSIGTERMを送信します。プロセスが適時に停止しない場合は、SIGKILLをフォローアップします。その後、実際のNodeJSプロセスは保証されます。

それを修正する方法

で実行するコマンドExecStart=は、実際のサーバーが起動するとすぐに終了するため、デフォルトのを使用することはできませんType=simple。別のサービスタイプを指定する必要があります。

を使用できますType=forking。このタイプでman systemd.serviceは、PIDFile=オプションの使用をお勧めします。そのため、NodeJSサーバーがそれ自体のPIDファイルを作成する場合(またはforeverコマンドにオプションを追加して、そのためのPIDファイルを作成する場合)、その場所を通知する必要systemdがあります。

[Service]
Type=forking
PIDFile=/absolute/path/to/nodejs.pid
User=rails
... <the rest as before>

場合はType=forkingあなたのために動作しません、あなたは指定することができType=oneshotRemainAfterExit=yes

これにより、サービスの開始時と停止時systemdExecStart=コマンドを実行するだけで、ExecStop=他のことは気にしません。

systemdただし、サービスが最後に停止状態または開始状態に設定されたかどうかは覚えています。したがって、このサービスに依存する別のサービスを設定し、NodeJSサービスを手動で停止した場合、他のサービスは自動的に停止せず、NodeJSサービスを使用できないときに間違いなくエラーを返します。


3番目のオプションは、foreverコマンドを完全にスキップしてsystemd、NodeJSプロセスを再起動するジョブを実行することです。その場合、nodejs.serviceユニット全体は次のようになります。

[Unit]
Description=nodejs server

[Service]
User=rails
Group=rails
ExecStart=/home/rails/NodeJSserver/server.js
Restart=always

[Install]
WantedBy=multi-user.target

他のオプションを追加できます。

たとえばRestartSec=5、サービスが予期せず停止した場合にサービスの再起動を試みる前に5秒のスリープを指定して、何らかの理由でサービスが再起動した直後にサービスが停止し続ける場合に頻繁な再起動の試行によってシステムリソースが占有されることを回避できます。(デフォルトRestartSec=値は100ミリ秒です。)

または、特定の終了ステータス値を返したサービスを再起動したいが、他のサービスでは失敗したと考えられる場合は、そのためのオプションもあります。


停止していないサービスがあり、適切に開始しません(サービスは開始しますが、systemctlプロセスは終了しません)。私の場合はそれを追加したいだけでRestart=always、.service構成ファイルに追加するだけで済みました。
Andy Forceno
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.