使用systemd启动大量服务

使用systemd启动大量服务

我想使用 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 单元文件,其中包含显式依赖链。以下是一些需要考虑的其他模式:

  1. systemd允许您在运行时设置资源控制参数,语法如下:

    systemctl --runtime set-property foobar.service CPUShares=777

因此,您可以在启动期间限制您的设备,使每个设备使用较少的 CPU,然后一旦事情平静下来,就允许它们使用更多的 CPU。这似乎比需要的更难,这让我想到了下一个选择......

  1. 在 中man systemd.resource-control,您会发现有一个StartupCPUShares=与 选项不同的选项CPUShares=。我会尝试对 CPU 进行节流,StartupCPUShares=看看是否能产生您想要的结果。

就我个人而言,我使用了一种技术含量非常低的路线来解决这样的问题。我一次开始了一系列服务,在服务开始之间有一个“睡眠”。这使用了一些 bash 脚本而不是system,但效果很好。值得庆幸的是,我也没有要求绝对尽快将所有服务上线。

我可能会围绕系统的下一个迭代进行设计systemd,并且会尝试使用StartupCPUShares=自己来看看这是否是解决问题的更好方法。

相关内容