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'.
서비스가 시작되지 않는 이유를 어떻게 알 수 있나요?
답변1
Type=
귀하의 서비스는 해당 섹션에 지정되어 있지 않으므로 [Service]
귀하 systemd
가 의미한다고 가정합니다 Type=simple
.
즉, 시작된 프로세스는 서비스가 실행되는 동안 systemd
계속 실행됩니다 . 하지만 하나의 명령만 실행한 다음 종료하는 ExecStart=
것 같습니다 . start.sh
그건forever
명령: 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
PID 파일을 생성하도록 하는 경우) 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 서비스를 사용할 수 없는 경우 의심할 여지 없이 오류를 반환합니다.
세 번째 옵션은 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
다른 옵션을 추가할 수 있습니다.
예를 들어 서비스가 예기치 않게 종료된 경우 서비스를 다시 시작하기 전에 대기 시간을 5초로 지정하면 RestartSec=5
어떤 이유로 서비스가 다시 시작된 후 즉시 종료되는 경우 잦은 다시 시작 시도로 인해 시스템 리소스가 소모되는 것을 방지할 수 있습니다. (기본값 RestartSec=
은 100밀리초입니다.)
또는 특정 종료 상태 값을 반환할 때 서비스를 다시 시작하고 다른 종료 상태 값에서는 실패하도록 고려하는 경우 몇 가지 옵션이 있습니다.