我想使用 systemd 启动大量(例如 256 个)服务。幸运的是,systemd 提供了切片,这使得重用服务描述变得非常容易。但同时启动多个进程会杀死系统,因为每个进程都会进行一些启动计算,这会将负载推至 50 以上。
是否可以使用切片为所有服务定义依赖链,After=service@%(i-1).service Wants=service@%(i-1).service?或者是否可以定义类似服务池之类的东西,然后 systemd 管理服务的启动,即不是一次全部运行,而是一次启动 10 个服务,然后再启动下一个块?
答案1
我使用 找到了一个很好的解决方案ExecStartPost
。
% systemctl --user cat example@
# /home/joerg/.config/systemd/user/[email protected]
[Unit]
Description=Example of service farm; instance %i
[Service]
Type=simple
ExecStart=/bin/sleep 99999
ExecStartPost=/bin/sh -c 'test %i -gt 0 || exit 0 ; systemctl --no-block --user start %p@$((%i - 1))'
% systemctl --user start example@2
% systemctl --user status example.slice
● example.slice
Loaded: loaded
Active: active since Thu 2017-04-27 11:04:43 CEST; 27min ago
CGroup: /user.slice/user-1000.slice/[email protected]/example.slice
├─[email protected]
│ └─19423 /bin/sleep 99999
├─[email protected]
│ └─19420 /bin/sleep 99999
└─[email protected]
└─19417 /bin/sleep 99999
答案2
不,systemd 不支持类似Wants=service@%(i-1).service?
.
但是,您可以编写一个简单的脚本来写出 256 个类似的 systemd 单元文件,其中包含显式依赖链。以下是一些需要考虑的其他模式:
systemd
允许您在运行时设置资源控制参数,语法如下:systemctl --runtime set-property foobar.service CPUShares=777
因此,您可以在启动期间限制您的设备,使每个设备使用较少的 CPU,然后一旦事情平静下来,就允许它们使用更多的 CPU。这似乎比需要的更难,这让我想到了下一个选择......
- 在 中
man systemd.resource-control
,您会发现有一个StartupCPUShares=
与 选项不同的选项CPUShares=
。我会尝试对 CPU 进行节流,StartupCPUShares=
看看是否能产生您想要的结果。
就我个人而言,我使用了一种技术含量非常低的路线来解决这样的问题。我一次开始了一系列服务,在服务开始之间有一个“睡眠”。这使用了一些 bash 脚本而不是system
,但效果很好。值得庆幸的是,我也没有要求绝对尽快将所有服务上线。
我可能会围绕系统的下一个迭代进行设计systemd
,并且会尝试使用StartupCPUShares=
自己来看看这是否是解决问题的更好方法。