为什么我自制的服务运行几天后,systemd 会将其标记为“解冻”?

为什么我自制的服务运行几天后,systemd 会将其标记为“解冻”?

我在运行我自己制作的服务时发现了“解冻”的奇怪标签,systemctl status XXX如下所示: 在此处输入图片描述

相反,我发现它通过以下方式运行多个线程htop在此处输入图片描述

一开始我以为是python的问题,直到我发现一个golang二进制文件也遇到了同样的问题:

[root]# systemctl status auto_quote
● auto_quote.service - run run_quotelive.sh ## <-change run_XXX.sh
   Loaded: loaded (/usr/lib/systemd/system/auto_quote.service; enabled; vendor preset: disabled)
   Active: active (running) (thawing) since Wed 2023-06-21 15:05:51 CST; 1 months 18 days ago
 Main PID: 1765370 (bash)
    Tasks: 8 (limit: 5366)
   Memory: 56.5M
   CGroup: /system.slice/auto_quote.service
           ├─1765370 /bin/bash /root/run_quotelive.sh ## <-change run_XXX.sh
           └─1765372 ./quotelive

[root]# cat /lib/systemd/system/auto_quote.service
[Unit]
Description=run run_quotelive.sh ## <-change run_XXX.sh
After=network.service


[Service]
Type=simple
ExecStart=/bin/bash /root/run_quotelive.sh ## <-change run_XXX.sh
Restart=on-failure
RestartSec=3
## systemd bears daemon duty

[Install]
WantedBy=multi-user.target

run_quotelive.sh运行的bash 脚本如下auto_quote.service

# substitute PATH with the desired Abusolute path of the program, binary or script
# substitute COMMAND with the shell command to run the program, binary or script
# i.e. binary/executable named as XXX, change it to ./XXX
# i.e. python3 script named as XXX.py, change it to python3 XXX.py
# the script below would run it at background and leave starting/failing time
# as well as program output( both normal print and errors) into PATH/out.log
cd /root/quotelive
cmd='./quotelive'
newcmd="$cmd &>> out.log"
echo -e '\n'  `date +'%Y/%m/%d %a, %X'`: STARTING - "$cmd" '\n'  >> out.log
eval $newcmd
echo -e '\n'  `date +'%Y/%m/%d %a, %X'`: PROCESS FAILED  >> out.log
exit 5 # make an error exit for service to restart

那么我的版本auto_quote.service或有什么问题吗run_quotelive.sh


我修改了脚本以便能够和平退出:

cd /root/quotelive
cmd='./quotelive'
echo -e '\n'  `date +'%Y/%m/%d %a, %X'`: STARTING - "$cmd" '\n'  >> out.log
$cmd >>out.log 2>&1
if [ $? -ne 0]; then
  echo -e '\n'  `date +'%Y/%m/%d %a, %X'`: PROCESS FAILED  >> out.log
  exit 5 # make an error exit for service to restart
fi

用于测试目的您只需更改/root/quotelive到您想要的任何目录,然后./quotelive更改到python3 -m http.server 12345,这也是一个永远服务的服务器。

但它继续发布解冻信息。我还注意到,quotelive应该重定向到的程序的打印输出/root/quotelive/out.log也出现在了 中systemctl status auto_quote

答案1

不清楚应quotelive该做什么,但显然它会经常使用 exit 5 指令退出。解冻意味着 systemd 认为永远重启失败的服务不是一个好主意,因为如果它总是失败,就应该修复它,而不是浪费资源,所以在几次重启后它就会解冻。

您遇到的第一个问题是,您运行后台作业,然后让exit 5systemd 认为它失败了,但事实并非如此。这样,您就永远创建了 的实例quotelive

如果quotelive程序打算永远运行,您应该使用:

# substitute PATH with the desired Abusolute path of the program, binary or script
# substitute COMMAND with the shell command to run the program, binary or script
# i.e. binary/executable named as XXX, change it to ./XXX
# i.e. python3 script named as XXX.py, change it to python3 XXX.py
# the script below would run it at background and leave starting/failing time
# as well as program output( both normal print and errors) into PATH/out.log
cd /root/quotelive
cmd='./quotelive'
newcmd="$cmd >> out.log"
echo -e '\n'  `date +'%Y/%m/%d %a, %X'`: STARTING - "$cmd" '\n'  >> out.log
eval $newcmd && exit 0
echo -e '\n'  `date +'%Y/%m/%d %a, %X'`: PROCESS FAILED  >> out.log
exit 5 # make an error exit for service to restart

如果它应该运行并执行作业然后重新启动:Restart=Always在服务文件中使用。

虽然这个包装脚本看起来很奇怪,但您可以考虑quotelive直接从 systemd 运行。

相关内容