我正在使用 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
只运行一个命令然后退出。那就是命令forever
:将forever start
目标命令作为守护进程启动,或者换句话说,在后台启动。命令完成后forever start
,正在运行的 shellstart.sh
将退出。此时,
systemd
认为此服务失败。但是等等,分配给该服务的控制组仍然有一个正在运行的进程。“所以,”想systemd
,“它不仅失败了,而且它本身也留下了一个烂摊子。不能这样。” 由于没有KillMode=
或未KillSignal=
指定,systemd
继续使用其默认值并为该控制组中的任何剩余进程发送 SIGTERM,如果它们没有及时停止,则使用 SIGKILL 跟进。在那之后,你的实际 NodeJS 进程肯定会死掉。如何修复它
由于您运行的命令
ExecStart=
将在实际服务器启动后立即退出,因此您不能使用默认的Type=simple
. 您必须指定其他服务类型。你可以使用
Type=forking
. 对于这种类型,man systemd.service
建议使用PIDFile=
选项,因此如果您的 NodeJS 服务器为自己创建一个 PID 文件(或者您向forever
命令添加选项以使其为其创建一个),您应该systemd
知道它将在哪里。如果
Type=forking
不适合您,那么您可以Type=oneshot
使用RemainAfterExit=yes
.这使得在启动服务和停止服务时
systemd
只运行ExecStart=
命令ExecStop=
,而不关心其他任何事情。systemd
不过,仍会记住该服务最后一次设置为停止状态还是启动状态。因此,如果您将另一个服务设置为依赖此服务,然后手动停止您的 NodeJS 服务,则其他服务不会自动停止,并且当它无法使用您的 NodeJS 服务时无疑会返回错误。第三个选项是
forever
完全跳过该命令,让我们systemd
重新启动 NodeJS 进程。在这种情况下,您的整个nodejs.service
单位将是:您可以添加其他选项。
例如,您可以指定
RestartSec=5
在服务意外终止时尝试重新启动服务之前指定一个 5 秒的睡眠时间,以避免在您的服务由于某种原因重新启动后立即终止时频繁尝试重新启动而占用系统资源。(默认RestartSec=
值为 100 毫秒。)或者,如果您希望服务在返回某些特定退出状态值时重新启动,但认为它在其他情况下失败,那么也有相应的选项。