如何配置多个 systemd 服务以使用一个计时器?

Sel*_*ott 4 systemd

我注意到一些 systemd 文档和操作文档中关于如何配置一个或多个服务以使用相同计时器的方法的一些显着变化。

就我已经能够拼凑起来(尽管我可能是错的)这将描述服务和计时器文件中的WantedByUnit参数需要设置为(此处不使用实际代码示例 - 以减少发布长度)用于单个服务,相反,使用单个计时器的多个服务配置:

单个服务的定时器

My.Service1 'WantedBy' Param: N/A (1)
My.Timer 'Unit' Param: My.Service1 (2)
My.Timer 'WantedBy' Param: MultiUser/Basic.Target (3) 
Run Code Online (Sandbox Code Playgroud)

(1)服务文件不需要带有 WantedBy 参数的 [Install] 部分。

(2)在计时器的 [Timer] 部分,Unit 参数应指向 My.Service1 服务文件。

(3)定时器文件有一个 WantedBy 参数,它指向一些将用于启动它的特殊系统目标。

多个服务的定时器

My.Service1 'WantedBy' Param: Timer.Target (1)
My.Service2 'WantedBy' Param: Timer.Target (1)
My.Service3 'WantedBy' Param: Timer.Target (1)
Timer 'Unit' Param: Timer.Target (2)
Timer 'WantedBy' Param: ???
Run Code Online (Sandbox Code Playgroud)

(1)所有服务都需要使用 WantedBy 参数连接到同一个定义的目标。

(2) [Timer] Unit 参数也应该指向目标。

有关后一种配置的示例,请参阅此操作方法。我将其视为示例 1。但是,我发现了其他与此不同的操作示例(见下文)。

示例 2示例 3说它应该像这样配置:

My.Service1 WantedBy: Timer.Target
My.Service2 WantedBy: Timer.Target
My.Service3 WantedBy: Timer.Target
Timer 'Unit' Param: My.Service1 (1)
Timer 'WantedBy' Param: MultiUser/Basic.Target
Run Code Online (Sandbox Code Playgroud)

(1) 这必须是文档中的一个疏忽,因为如果您让单元只指向多个服务中的一个,则其他服务无法使用计时器。这可能是由于在那里使用“见上”方法将读者引回到单一服务配置,而没有实际提及(重要)需要更改的内容。

然后在示例 4 中,它的配置看起来实际上可以工作,但它通过直接在/etc/systemd/system/Timer.Target.wants/子目录下创建服务文件,以不同的方式将服务与目标连接起来排除服务文件中的任何 WantedBy 参数。因此:

My.Service1 'WantedBy' Param: N/A
My.Service2 'WantedBy' Param: N/A
My.Service3 'WantedBy' Param: N/A
Timer 'Unit' Param: Timer.Target
Timer 'WantedBy' Param: MultiUser/Basic.Target
Run Code Online (Sandbox Code Playgroud)

我见过的示例 1 和示例 4 之间的混合方法是在/etc/systemd/system/目录(默认位置)中创建服务文件,并在/etc/systemd下创建指向这些服务文件的符号链接/system/Timer.Target.wants文件并排除服务文件中的 WantedBy 参数(在功能上等同于示例 4),而另一个配置使用符号链接方法,但另外在服务文件中包含了 WantedBy 参数(这似乎多余的和不必要的)。

对于示例 4 和混合方法,我的问题是这样的:如果声明一个 WantedBy 参数应该指示 systemd 为你做这件事,为什么要把任何东西放在*.wants目录下是必要的(如解释中所述此页面上的那个参数)?

在令人困惑的多种方法中,任何人都可以阐明使用相同计时器配置多个服务的最佳方法吗?

小智 5

如果要使用单个计时器激活多个​​服务,请在两者之间插入一个目标:

定时器单元,我们称之为 foo.timer:

[Unit]
Description=My timer that runs saturdays, 9am and triggers foo.target

[Timer]
OnCalendar=Sat 9:00
Unit=foo.target

[Install]
WantedBy=timers.target
Run Code Online (Sandbox Code Playgroud)

目标单元,我们称之为 foo.target:

[Unit]
Description= My target unit, that groups my two services xxx.service and yyy.service
Wants=xxx.service yyy.service
After=xxx.service yyy.service

[Install]
Also=foo.timer
Run Code Online (Sandbox Code Playgroud)

然后是两个服务 xxx.service 和 yyy.service:

[Unit]
Description=My service XXX

[Service]
ExecStart=/bin/echo I am XXX

[Install]
Also=foo.timer
Run Code Online (Sandbox Code Playgroud)
[Unit]
Descritpion=My service YYY

[Service]
ExecStart=/bin/echo I am YYYY

[Install]
Also=foo.timer
Run Code Online (Sandbox Code Playgroud)

将这四个单元文件(foo.timer、foo.target、xxx.service、yyy.service)复制到 /etc/systemd/systemd/ 中。然后通过发出“systemctl enable --now foo.timer”来启用和启动计时器。这会将 foo.timer 挂接到 timers.target,它是一个通用目标,应该拉入系统上定义的所有各种计时器。请注意,您也可以执行“systemctl enable foo.target”顺便说一句,以及“systemctl enable zzz.service”,因为这些单元中的 Also= 行将启用请求传播到 foo.timer。


Mar*_*erg 0

systemd 计时器总是激活一个单元。

如果您想按相同的计划激活两个单元,为了清晰起见,我建议创建两个包含相同计划的计时器文件。

否则,您可以创建一个“服务单元”文件来启动您想要的两个服务。

我不认为“WantedBy=”对于计时器单元来说是一个特别有用的概念。