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
.
매뉴얼 페이지에는 다음과 같이 나와 있습니다.
simple로 설정하면 서비스 관리자는 기본 서비스 프로세스가 분기된 후 즉시 장치가 시작되는 것으로 간주합니다. ExecStart=로 구성된 프로세스가 서비스의 주요 프로세스일 것으로 예상됩니다....
즉, 스크립트가 주요 프로세스입니다. 여러 프로세스를 시작한 다음 종료합니다. systemd
기본 프로세스 종료를 확인한 다음 더 이상 상위 프로세스가 없는 하위 프로세스 정리를 진행합니다.
반대로 당신은 Type=forking
.
분기로 설정된 경우 ExecStart=로 구성된 프로세스는 시작의 일부로 분기()를 호출해야 합니다. 시작이 완료되고 모든 통신 채널이 설정되면 상위 프로세스가 종료될 것으로 예상됩니다. 하위 프로세스는 계속해서 기본 서비스 프로세스로 실행되며, 상위 프로세스가 종료되면 서비스 관리자는 해당 유닛이 시작된 것으로 간주합니다. 이는 기존 UNIX 서비스의 동작입니다. 이 설정을 사용하는 경우 systemd가 서비스의 기본 프로세스를 안정적으로 식별할 수 있도록 PIDFile= 옵션도 사용하는 것이 좋습니다.
이 경우 스크립트가 종료된 후에도 하위 프로세스가 계속 유지될 수 있습니다. 을 추가하면 Type=forking
상황이 더 좋아질 것입니다.
디자인에 몇 가지 다른 문제가 있다는 점에 유의하세요. 변경 사항만 변경된 경우에는 Type=forking
여전히 몇 가지 문제가 있습니다.
- 프로세스 중 하나가 종료되면 systemd는 이것이 MainPID인지 결정하고 전체 서비스를 고려할 수도 있고 그렇지 않을 수도 있습니다
inactive (dead)
. 작성하는 것이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.service
lavalink