配置SystemD服务以定期重新启动
1. 简介
有时,我们需要重启systemd 服务来解决运行错误。我们可以在 Linux 中使用各种方法自动执行此操作。在本教程中,我们将研究三种可以定期重启systemd服务的方法。
2. 使用 Oneshot 服务
**Oneshot 服务是执行特定任务并在该任务完成时终止的system服务。**换句话说,这个过程是短暂的。我们可以使用计时器和 oneshot 服务 定期启动systemd服务。
我们将使用计时器服务来触发 oneshot 服务。随后,oneshot 服务将负责重启我们的systemd服务。我们在*/etc/systemd/system目录中创建所有systemd服务单元文件。我们创建了三个名为my-service.service*、oneshot.service和my-service.timer的systemd单元文件。让我们定义一个名为 *my-service.service *的服务,它将执行一个特定的任务:
$ sudo vi my-service.service
[Unit]
Description=Simple service
[Service]
Type=simple
ExecStart=/usr/bin/logger hello
[Install]
WantedBy=multi-user.target
该服务将在系统日志中进行简单的输入。在我们的例子中,我们正在记录消息“ hello ”。因此,一旦服务运行,我们应该在日志中看到“ hello ”输出。随后,让我们创建oneshot.service文件:
$ sudo vi oneshot.service
[Unit]
Description=One shot service
[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl restart my-service.service
[Install]
WantedBy=multi-user.target
oneshot.service文件将重新启动my-service.service。最后,我们设置systemd计时器:
$ sudo vi my-service.timer
[Unit]
Description=Run oneshot service periodically
[Timer]
Unit=oneshot.service
OnCalendar=Mon..Fri 10:30
[Install]
WantedBy=timers.target
oneshot.service文件将由我们创建的systemd计时器触发。在此示例中,systemd服务my-service将在工作日的上午 10:30 重新启动。此外,我们像启动任何其他systemd服务一样启动计时器:
$ systemctl enable --now my-service.timer
我们可以通过列出systemd计时器来查看计时器何时运行以及何时运行:
$ systemctl list-timers
NEXT LEFT LAST PASSED UNIT ACTIVATES
Fri 2021-12-24 09:39:42 SAST 3min 13s left Fri 2021-12-24 08:36:22 SAST 1h 0min ago dnf-makecache.timer dnf-makecache.service
Fri 2021-12-24 10:30:00 SAST 53min left Fri 2021-12-24 09:22:03 SAST 14min ago my-service.timer oneshot.service
检查系统日志后,我们看到我们的服务确实运行了:
$ journalctl --since "5 minutes ago"
Dec 24 10:30:03 localhost.localdomain systemd[1]: Started Simple service.
Dec 24 10:30:03 localhost.localdomain systemd[1]: oneshot.service: Succeeded.
Dec 24 10:30:03 localhost.localdomain systemd[1]: Started One shot service.
Dec 24 10:30:03 localhost.localdomain root[4385]: hello
Dec 24 10:30:03 localhost.localdomain systemd[1]: my-service.service: Succeeded.
3. 使用RuntimeMaxSec和重启 选项
**或者,我们可以使用RuntimeMaxSec选项在运行一定时间后 终止systemd服务。**此外,我们将Restart描述符设置为always。此选项确保服务始终重新启动。此方法不适用于 oneshot 服务。这是因为 oneshot 服务总是在任务完成时终止。
因此, 在这种情况下无法使用my-service.service单元文件。让我们创建一个简单的systemd服务并将其命名为my-service1.service:
$ sudo vi my-service1.service
[Unit]
Description=Simple service
[Service]
ExecStart=/usr/bin/python3 /root/app.py
RuntimeMaxSec=180s
Restart=always
[Install]
WantedBy=multi-user.target
该服务将执行无限期运行的基本 python 程序。此外,此服务将在 180 秒后终止并再次重新启动:
Dec 24 18:50:57 localhost systemd[1]: Started Simple service.
Dec 24 18:53:57 localhost systemd[1]: my-service1.service: Service reached runtime time limit. Stopping.
Dec 24 18:53:57 localhost systemd[1]: my-service1.service: Failed with result 'timeout'.
Dec 24 18:53:57 localhost systemd[1]: my-service1.service: Service RestartSec=100ms expired, scheduling restart.
Dec 24 18:53:57 localhost systemd[1]: my-service1.service: Scheduled restart job, restart counter is at 1.
Dec 24 18:53:57 localhost systemd[1]: Stopped Simple service.
Dec 24 18:53:57 localhost systemd[1]: Started Simple service.
4.使用Cronjob
或者,我们可以在crontab而不是服务文件中指定我们想要运行的命令。让我们编辑我们的crontab:
$ crontab -e
30 10 * * 1-5 /usr/bin/systemctl restart my-service.service
在这里,我们的条目指定我们要在每个工作日的上午 10:30 重新启动my-service.service。此外,如果该服务被禁用,它将再次启动。