当前位置: 首页 > 科技观察

在Linux上使用systemd设置计时器

时间:2023-03-15 16:58:04 科技观察

学习使用systemd创建计时器以启动游戏服务器。之前,我们了解了如何在启动和关闭时、启用设备时以及进行文件系统更改时手动启用和禁用systemd服务。计时器添加了另一种启动服务的方式,基于...时间。尽管类似于cron作业,但systemd计时器稍微灵活一些。让我们看看它是如何工作的。“在计时器上运行”让我们扩展您在本系列前两篇文章中设置的Minetest服务器,作为如何使用计时器单元的第一个示例。如果您还没有阅读过这些文章,现在就可以查看它们。您将通过创建一个在服务器启动后1分钟而不是立即运行游戏服务器的计时器来“改进”Minetest服务器。这样做的原因可能是在开始之前可能使用了其他服务,比如给其他玩家发邮件告诉他们游戏已经准备好了,你要确保其他服务(比如网络)在开始之前已经完全正常运行。最终,你的minetest.timer单元看起来像这样:一点都不难。与往常一样,它以[Unit]和一条描述该单元功能的消息开头,这里没有什么新内容。[Timer]部分是新的,但其用途不言自明:它包含有关何时启动服务以及启动哪个服务的信息。在此示例中,OnBootSec是一个指示systemd在系统启动后运行该服务的指令。其他指令是:OnActiveSec=,它告诉systemd在计时器启动后要运行服务多长时间。OnStartupSec=,再一次,它告诉systemd在systemd进程启动后要运行该服务多长时间。OnUnitActiveSec=,告诉systemd在上次由计时器激活的服务启动服务后要运行该服务多长时间。OnUnitInactiveSec=,告诉systemd在最后一次定时器激活的服务停用后运行服务多长时间。继续minetest.timer单元,basic.target通常用作延迟启动服务的同步点。这意味着可以在安装本地挂载点或交换设备、套接字、计时器、路径单元和其他基本初始化过程后运行minetest.timer单元。正如在第二篇文章的systemd单元中解释的那样,目标就像旧的运行级别,它可以让你的计算机进入某种状态,或者告诉你的服务达到某种状态后开始运行。您在前两篇文章中配置的minetest.service文件最终看起来像这样:/usr/games/minetest--serverExecStartPost=/home//bin/mtsendmail.sh“准备好了吗?”“Minetest正在启动”TimeoutStopSec=180ExecStop=/home//bin/mtsendmail.sh“去睡觉吧。睡衣之夜!”"MinetestStoppingin2minutes"ExecStop=/bin/sleep120ExecStop=/bin/kill-2$MAINPID[Install]WantedBy=multi-user.target此处无需更改。但是您需要从以下位置安装mtsendmail.sh(发送电子邮件的脚本):#!/bin/bash#mtsendmailsleep20echo$1|mutt-F/home//.muttrc-s"$2"my_minetest@mailing_list.comsleep10更改为:#!/bin/bash#mtsendmail.shecho$1|mutt-F/home/paul/.muttrc-s"$2"pbrown@mykolab.com你所做的是删除Bash脚本中那些糟糕的停顿。Systemd现在负责等待。让它运行以确保一切正常,禁用minetest.service:sudosystemctldisableminetest这使得它在系统启动时不启动;然后,相反地,启用minetest.timer:sudosystemctlenableminetest.timer现在你可以重新启动服务器已启动,当你运行sudojournalctl-uminetest.*你将看到minetest.service单元在minetest后大约一分钟开始运行.timer单元执行。图一:minetest.timer运行约1分钟后,minetest.service开始运行。systemd日志中minetest.timer的启动时间是09:08:33,而minetest.service的启动时间是09:09:18。它们之间的时间不到1分钟,有几点需要注意:首先,请记住我们说过OnBootSec=指令计算自引导完成后服务启动的时间。当minetest.timer的时间到来时,引导程序已在几秒钟前完成。另一件事是systemd为自己设置了运行误差范围(默认为1分钟)。这有助于在多个资源密集型进程同时运行时分配负载:通过分配1分钟,systemd可以等待某些进程关闭。这也意味着minetest.service将在引导完成后的1到2分钟内启动。但没有人知道确切的时间。顺便说一句,您可以使用AccuracySec=指令修改误差范围。您还可以检查系统上所有计时器何时运行或上次运行时间:systemctllist-timers--all图2:检查计时器何时运行或上次运行时间***要考虑的一件事最重要的是你应该使用什么格式来表示一段时间。Systemd在这方面非常灵活:2h、2小时或2hr都可以用来表示2小时。对于“seconds”,您可以使用seconds、second、sec和s。“分钟”也是如此:minutes、minute、min和m。您可以检查mansystemd.time以查看systemd理解的所有时间单位。下次下次你会看到如何使用日历中的日期和时间定期运行服务,以及如何通过将计时器与设备单元组合来在插入某些硬件时运行服务。