CentOS 7에서 내 systemctl 서비스가 시작되지 않는 이유를 어떻게 알 수 있나요?

CentOS 7에서 내 systemctl 서비스가 시작되지 않는 이유를 어떻게 알 수 있나요?

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 파일을 생성하는 경우(또는 명령에 옵션을 추가하여 foreverPID 파일을 생성하도록 하는 경우) systemd이를 알려야 합니다. 어디에 있을까요?

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

그래도 문제 Type=forking가 해결되지 않으면 .Type=oneshotRemainAfterExit=yes

systemd이를 통해 서비스를 시작하고 중지할 때 다른 작업에 신경 쓰지 않고 명령만 실행할 수 있습니다 .ExecStart=ExecStop=

systemd그러나 서비스가 마지막으로 중지됨 상태로 설정되었는지 또는 시작됨 상태로 설정되었는지는 여전히 기억됩니다. 따라서 이 서비스에 의존하도록 다른 서비스를 설정한 다음 NodeJS 서비스를 수동으로 중지하면 다른 서비스는 자동으로 중지되지 않으며 NodeJS 서비스를 사용할 수 없는 경우 의심할 여지 없이 오류를 반환합니다.


세 번째 옵션은 forever명령을 완전히 건너뛰고 systemdNodeJS 프로세스를 다시 시작하는 작업을 수행하도록 하는 것입니다. 이 경우 전체 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밀리초입니다.)

또는 특정 종료 상태 값을 반환할 때 서비스를 다시 시작하고 다른 종료 상태 값에서는 실패하도록 고려하는 경우 몇 가지 옵션이 있습니다.

관련 정보