데비안 서비스가 시작 시 파일을 올바르게 시작하지 않습니다.

데비안 서비스가 시작 시 파일을 올바르게 시작하지 않습니다.

다음 내용으로 호출 botstart.service된 파일이 있습니다 ./etc/systemd/system

[Unit]
Description=Start all discord bots (AntiSpam, AutoChat, Nyoko, Helper) and the lavalink server.

[Service]
ExecStart=/bin/bash /home/scripts/start.sh

[Install]
WantedBy=multi-user.target

나는 그것을 시작했고 systemctl enable botstart 활성화되었다고 말했습니다. VPS를 재부팅했지만 스크립트가 실행되지 않았습니다. 내가 그랬더니 systemctl status botstart다음과 같이 나타났습니다.

root@Hetzner-01:~# systemctl status botstart
● botstart.service - Start all discord bots (AntiSpam, AutoChat, Nyoko, Helper)
   Loaded: loaded (/etc/systemd/system/botstart.service; enabled; vendor preset:
   Active: inactive (dead) since Wed 2021-10-27 01:37:10 CEST; 50s ago
  Process: 481 ExecStart=/bin/bash /home/scripts/start.sh (code=eited, status=0
 Main PID: 481 (code=existed, status=0/SUCCESS)

Oct 27 01:37:07 Hetzner-01 systemd[1]: STarted Start all discord bots (antiSpam,
Oct 27 01:37:10 Hetzner-01 bash[481]: Started all bots
Oct 27 01:37:10 Hetzner-01 systemd[1]: botstart.service: Succeeded.
lines 1-9/9 (END)...skipping...
● botstart.service - Start all discord bots (AntiSpam, AutoChat, Nyoko, Helper) and the lavalink server.
   Loaded: loaded (/etc/systemd/system/botstart.service; enabled; vendor preset: enabled)
   Active: inactive (dead) since Wed 2021-10-27 01:37:10 CEST; 50s ago
  Process: 481 ExecStart=/bin/bash /home/scripts/start.sh (code=eited, status=0/SUCCESS)
 Main PID: 481 (code=existed, status=0/SUCCESS)

스크립트를 수동으로 실행하면 작동하지만 서비스로는 아니지만 서비스가 실행되고 스크립트가 실행됩니다(서비스 상태가 이를 알려줍니다.). 이유를 아는 사람이 있습니까? 스크립트 코드는 다음과 같습니다.

screen -dmS antispam bash -c "cd /home/AntiSpam; python3.8 main.py"
screen -dmS autochat bash -c "cd /home/AutoChat; python3.8 main.py"
screen -dmS helper bash -c "cd /home/Helper; python3.8 main.py"
screen -dmS lavalink bash -c "cd /home/Lavalink; python3.8 main.py"
sleep 3
screen -dmS nyoko bash -c "cd /home/Nyoko; python3.8 main.py"
echo "Started all bots"

답변1

[Service]섹션 에서 Type=. 즉, 기본값은 Type=simple.

매뉴얼 페이지에는 다음과 같이 나와 있습니다.

단순으로 설정된 경우 서비스 관리자는 기본 서비스 프로세스가 분기된 직후에 장치가 시작된 것으로 간주합니다. ExecStart=로 구성된 프로세스가 서비스의 주요 프로세스일 것으로 예상됩니다....

즉, 스크립트가 주요 프로세스입니다. 여러 프로세스를 시작한 다음 종료됩니다. systemd기본 프로세스 종료를 확인한 다음 더 이상 상위 프로세스가 없는 하위 프로세스를 정리합니다.

대신에 당신은 원합니다 Type=forking.

분기로 설정되면 ExecStart=로 구성된 프로세스가 시작의 일부로 fork()를 호출할 것으로 예상됩니다. 시작이 완료되고 모든 통신 채널이 설정되면 상위 프로세스가 종료될 것으로 예상됩니다. 하위 프로세스는 계속해서 기본 서비스 프로세스로 실행되며, 서비스 관리자는 상위 프로세스가 종료되면 해당 단위가 시작된 것으로 간주합니다. 이는 기존 UNIX 서비스의 동작입니다. 이 설정을 사용하는 경우 systemd가 서비스의 주요 프로세스를 안정적으로 식별할 수 있도록 PIDFile= 옵션도 사용하는 것이 좋습니다.

이 경우 스크립트가 종료된 후에도 하위 프로세스가 계속 유지될 수 있습니다. 을 추가하면 Type=forking상황이 더 좋아질 것입니다.


디자인에 몇 가지 다른 문제가 있다는 점에 유의하세요. 유일한 변경 사항이 이라면 Type=forking여전히 몇 가지 문제가 있습니다.

  • 프로세스 중 하나가 종료되면 systemd는 그것이 MainPID인지 결정하고 전체 서비스를 고려할 수도 있고 그렇지 않을 수도 있습니다 inactive (dead). a에 글을 쓰면 PIDFile=도움이 될 수 있지만 이러한 프로세스 중 어느 것도 MainPID가 되도록 의도하지는 않은 것 같습니다.
  • 프로세스가 실패하면 systemd실패 상태를 보고하지 않을 수 있습니다. 다른 프로세스에 어떤 일이 발생해야 하는지는 확실하지 않습니다.

권장 사항 1: 각 프로세스를 자체 서비스로 분할합니다. 그러면 Type=simple작동합니다. 이렇게 하면 한 서비스에 장애가 발생하더라도 다른 봇에 영향을 주지 않고 해당 서비스를 감지하고 안정적으로 운영할 수 있습니다.

권장 사항 2: Restart=on-failure. 이렇게 하면 실패한 서비스가 자동으로 다시 시작될 수 있습니다(사람의 개입이 필요하지 않음).

bash권장사항 3: 어느 호출이 호출 screen하는지 호출하지 마세요 python3. Python을 직접 호출하면 됩니다. screen환경에서는 필요하지 않은 해결 방법입니다 systemd.

권장사항 4: 이를 구현하려면 sleep 3다음을 사용할 수 있습니다.ExecStartPre=

이러한 권장 사항을 따르면 nyoko.service다음과 같습니다.

[Unit]
Description=Nyoko discord bot

[Service]
WorkingDirectory=/home/Nyoko
ExecStartPre=/usr/bin/sleep 3
ExecStart=/usr/bin/python3 /home/Nyoko/main.py
Restart=on-failure

[Install]
WantedBy=multi-user.target

권장 사항 5: sleep너무 신뢰할 수 없습니다. 날씨가 좋은 날에는 3초가 낭비됩니다. 상황이 좋지 않은 날에는 그것만으로는 충분하지 않아 서비스가 실패하게 됩니다. 섹션에 의존하는 항목이 시작되기 전에 섹션 After=lavalink.service에 추가하는 것을 고려해보세요 . 시작되었음을 표시하는 일종의 신호가 있는 경우 (파일이 생성되거나 소켓이 열림) 대신 해당 신호를 트리거할 수 있습니다.[Unit]lavalink.servicelavalink

관련 정보