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'.
サービスの開始に失敗した理由を知るにはどうすればよいですか?
サービスのType=
が[Service]
セクションで指定されていないため、systemd
はType=simple
を意味していると想定します。
つまり、systemd
は、サービスが実行されている限り、ExecStart=
で開始されたプロセスが実行を継続することを期待します。しかし、start.sh
は1つのコマンドしか実行せずに終了するようです。つまり the forever
command :forever start
はターゲットコマンドをデーモンとして、つまりバックグラウンドで開始します。 forever start
コマンドが完了するとすぐに、start.sh
を実行しているシェルが終了します。
その時点で、systemd
はこのサービスが失敗したと見なします。ただし、そのサービスに割り当てられたコントロールグループには、まだ実行中のプロセスがあります。 「それで」とsystemd
は考えます、「失敗しただけでなく、それ自体が混乱を残しました。それはあり得ません。」 KillMode=
もKillSignal=
も指定されていないため、systemd
はデフォルトで続行し、そのコントロールグループ内の残りのプロセスにSIGTERMを送信します。タイムリーに、SIGKILLをフォローアップします。その後、実際のNodeJSプロセスは保証されます。
ExecStart=
で実行するコマンドは、実際のサーバーが起動するとすぐに終了するため、デフォルトのType=simple
を使用することはできません。別のサービスタイプを指定する必要があります。
Type=forking
を使用できます。このタイプでは、man systemd.service
はPIDFile=
オプションの使用をお勧めします。そのため、NodeJSサーバーがそれ自体のPIDファイルを作成する場合(またはforever
コマンドにオプションを追加して、それ)、それがどこにあるかをsystemd
に知らせる必要があります。
[Service]
Type=forking
PIDFile=/absolute/path/to/nodejs.pid
User=Rails
... <the rest as before>
Type=forking
が機能しない場合は、Type=oneshot
をRemainAfterExit=yes
と一緒に指定できます。
これにより、サービスを開始するときにsystemd
を実行するだけでExecStart=
コマンドを実行し、サービスを停止するときには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ミリ秒です。)
または、サービスが特定の終了ステータス値を返したときにサービスを再起動したいが、他のサービスでは失敗したと考える場合、そのためのオプションもあります。