如何使用 systemd 管理批处理作业的多个实例?

fle*_*ive 2 ubuntu service systemd

使用 systemd,我想管理具有以下属性的队列工作器的多个实例:

  1. 队列工作人员的数量应该是可配置的
  2. 每个队列工作人员应在失败时重新启动
  3. 运行单个命令来启动/停止/重新启动队列工作人员的所有实例
  4. 使用单个命令监视队列工作程序的所有实例是否正在运行。

我能够实现这些功能,但该解决方案的功能比诸如supervisord之类的替代方案要重。 有没有更简单的方法来单独使用 systemd 来管理多实例服务?

fle*_*ive 5

步骤:使用 systemd 管理服务的多个实例

\n
    \n
  1. 创建一个systemd模板单元,可以通过在单元的文件名中添加“@”来实现,然后手动创建与此模板不同的单元1
  2. \n
  3. 使用Restart=on-failure服务配置2中的设置。
  4. \n
  5. 创建一个不执行任何操作的主服务,然后使用 和 依赖项 3 使辅助服务依赖PartOf于该After服务WantedBy
  6. \n
  7. 将 systemctl 命令排队,查看是否有任何工作进程处于非活动状态;主进程的状态不提供信息。
  8. \n
\n

设置:systemd 单元文件

\n

创建这两个文件:

\n

/etc/systemd/system/queue_worker@.service:

\n
[Unit]\nDescription="Queue Worker instance %i"\nPartOf=queue_main.service\nAfter=queue_main.service\n\n[Service]\n# Pretend that the component is running\nExecStart=/bin/sleep infinity\nRestart=on-failure\n\n[Install]\nWantedBy=queue_main.service\n
Run Code Online (Sandbox Code Playgroud)\n

/etc/systemd/system/queue_main.service:

\n
[Unit]\nDescription=Queue Main\n\n[Service]\n# execute a dummy program, and keep the service active after exit\nType=oneshot\nExecStart=/bin/true\nRemainAfterExit=yes\n\n[Install]\nWantedBy=multi-user.target\n
Run Code Online (Sandbox Code Playgroud)\n

使用 systemd 模板创建多个服务实例

\n

首先,我们必须决定想要拥有的实例数量,然后通过 systemctl“启用”这些服务。这将为每个实例创建一个指向服务模板文件的符号链接:

\n
# systemctl enable queue_worker\\@{1..3}.service\nCreated symlink /etc/systemd/system/queue_main.service.wants/queue_worker@1.service \xe2\x86\x92 /etc/systemd/system/queue_worker@.service.\nCreated symlink /etc/systemd/system/queue_main.service.wants/queue_worker@2.service \xe2\x86\x92 /etc/systemd/system/queue_worker@.service.\nCreated symlink /etc/systemd/system/queue_main.service.wants/queue_worker@3.service \xe2\x86\x92 /etc/systemd/system/queue_worker@.service.\n
Run Code Online (Sandbox Code Playgroud)\n

使用 systemctl 启动和停止多个服务实例

\n

由于我们定义队列工作服务对队列主服务的依赖性的方式,启动queue_main.service将导致systemd启动每个工作服务:

\n
# systemctl start queue_main.service # launches all three worker instances successfully.\n# systemctl status queue_main.service\n\xe2\x97\x8f queue_main.service - Queue Main\n     Loaded: loaded (/etc/systemd/system/queue_main.service; enabled; vendor preset: enabled)\n     Active: active (exited) since Mon 2022-09-19 15:11:46 UTC; 2min 55s ago\n    Process: 404801 ExecStart=/bin/true (code=exited, status=0/SUCCESS)\n   Main PID: 404801 (code=exited, status=0/SUCCESS)\n\nSep 19 15:11:46 dev systemd[1]: Starting Queue Main...\nSep 19 15:11:46 dev systemd[1]: Finished Queue Main.\n\n# systemctl status\n[...]\n\xe2\x94\x9c\xe2\x94\x80system-queue_worker.slice\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80queue_worker@1.service\n\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80398812 /bin/sleep infinity\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80queue_worker@3.service\n\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80398817 /bin/sleep infinity\n\xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80queue_worker@2.service\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80398815 /bin/sleep infinity\n
Run Code Online (Sandbox Code Playgroud)\n

可以看到,queue_main.service启动成功触发了三个worker服务。但是,工作人员服务并不依赖于主要服务,我无法想出实现此目的的方法。此外,主要服务具有特殊的活动状态“活动(退出)”

\n

停止和重新启动工作服务也可以通过主服务直接实现:

\n
# systemctl stop queue_main # terminates all queue worker service instances\n# systemctl restart queue_main # restarts all queue worker service instances\n
Run Code Online (Sandbox Code Playgroud)\n

仅使用 systemctl 监控多个服务实例

\n

不幸的是,我们的现状queue_main.service并不能提供有关个别工人状况的信息。为了监控工人,我们需要检查他们的个人状态。我们可以通过以下方式获得适合脚本编写的输出:

\n
# kill -HUP 404818 # manually kill one worker to make the output more interesting\n\n# systemctl list-units "queue_worker@*.service" --all --no-legend # show the status of all instances\nqueue_worker@1.service loaded active   running "Queue Worker instance 1"\nqueue_worker@2.service loaded inactive dead    "Queue Worker instance 2"\nqueue_worker@3.service loaded active   running "Queue Worker instance 3"\n\n# systemctl list-units "queue_worker@*.service" --all --state=inactive --no-legend # show only inactive services\nqueue_worker@2.service loaded inactive dead "Queue Worker instance 2"\n
Run Code Online (Sandbox Code Playgroud)\n

该解决方案在 Ubuntu 20.04 和 systemd 245 上进行了测试

\n