如何构建多实例systemd服务配置?

时间:2015-10-09 12:26:36

标签: systemd

我正在尝试将systemd配置为能够执行同一服务的多个实例,但似乎我做错了,文档资源似乎不太清楚。

使用以下内容创建/lib/systemd/system/confluence@.service文件:

[Unit]
Description=Confluence %i
After=postgresql.service nginx.service

[Service]
Type=forking
ExecStart=/opt/atlassian/confluence-%i/bin/start-confluence.sh
ExecStartPre=/opt/atlassian/confluence-%i/bin/setenv.sh prestart

ExecStop=/opt/atlassian/confluence-%i/bin/stop-confluence.sh

TimeoutStopSec=5min
PIDFile=/opt/atlassian/confluence-%i/work/catalina.pid

[Install]
WantedBy=multi-user.target

到目前为止,非常好,systemctl enable confluence.test报告了成功(是的/ opt / atlassian / confluence-test /"发生了#34;以包含它所需要的内容。

但是,当我尝试使用systemctl start confluence启动服务时,我得到了:

root@atlas:/lib/systemd/system# systemctl start confluence@test.service
Job for confluence@test.service failed. See "systemctl status confluence@test.service" and "journalctl -xe" for details.
root@atlas:/lib/systemd/system# systemctl status confluence@test.service
● confluence@test.service - Confluence test
   Loaded: loaded (/lib/systemd/system/confluence@.service; enabled; vendor preset: enabled)
   Active: failed (Result: exit-code) since Fri 2015-10-09 13:25:28 BST; 7s ago
  Process: 16352 ExecStartPre=/opt/atlassian/confluence-%i/bin/setenv.sh prestart (code=exited, status=203/EXEC)

Oct 09 13:25:28 atlas systemd[1]: Starting Confluence test...
Oct 09 13:25:28 atlas systemd[1]: confluence@test.service: control process exited, code=exited status=203
Oct 09 13:25:28 atlas systemd[1]: Failed to start Confluence test.
Oct 09 13:25:28 atlas systemd[1]: Unit confluence@test.service entered failed state.
Oct 09 13:25:28 atlas systemd[1]: confluence@test.service failed.

不知何故,似乎systemd没有扩展"%i"这应该是实例名称。

2 个答案:

答案 0 :(得分:0)

我一直在网上跳来跳去,寻找创建我自己的systemd单元,模板和目标文件集所需的部分。这个问题出现在大量搜索结果中。在这种情况下,我认为我可以提供帮助,而不是寻求帮助。

我没有Confluence,也不会安装它进行测试,所以我主要是在猜测第一部分。

我认为问题在于%i说明符已被转义,并且可能在命令中创建了错误的路径。如果这是整个问题,那么更改为未转义的版本%I将是最简单的解决方案。您的文件/lib/systemd/system/confluence@.service将变为:

[Unit]
Description=Confluence %I
After=postgresql.service nginx.service

[Service]
Type=forking
ExecStart=/opt/atlassian/confluence-%I/bin/start-confluence.sh
ExecStartPre=/opt/atlassian/confluence-%I/bin/setenv.sh prestart

ExecStop=/opt/atlassian/confluence-%I/bin/stop-confluence.sh

TimeoutStopSec=5min
PIDFile=/opt/atlassian/confluence-%I/work/catalina.pid

[Install]
WantedBy=multi-user.target

另一方面,如果问题的根源不同,例如说明符未在命令中扩展,则仍可以使用包装脚本来实现相同的结果。 systemd可以消除对它们的需求,但是在较新的过程中使用较旧的系统通常会导致理论与实践不符。

在可能是其他所有内容的基础的目录中创建一个shell脚本。

使用以下方法创建/opt/atlassian/conflencectl

#!/usr/bin/env bash
# Check that there is a command to execute
if ( ! test -n "$1" ) {
  exit 1
}

# Check that there is an instance name to use
if ( ! test -n "$2" ) {
  exit 1
}

# Make the directory name stub for this instance
InstanceDirName="confluence-$2"

# Execute the proper command, based on the command from the unit file
case $1 in
  Start)
    /opt/atlassian/$InstanceDirName/bin/start-confluence.sh;
    ;;
  StartPre )
    /opt/atlassian/$InstanceDirName/bin/setenv.sh prestart;
    ;;
  Stop )
    /opt/atlassian/$InstanceDirName/bin/stop-confluence.sh;
    ;;
  *)
    exit 1;
esac

根据操作所需的内容,可以添加其他安全性,完整性或依赖性检查,例如测试目录或所需配置文件的存在。

您的systemd单位文件将变为:

[Unit]
Description=Confluence %I
After=postgresql.service nginx.service

[Service]
Type=forking
ExecStart=/opt/atlassian/conflencectl "Start" "%i"
ExecStartPre=/opt/atlassian/conflencectl "StartPre" "%i"

ExecStop=/opt/atlassian/conflencectl "Stop" "%i"

TimeoutStopSec=5min
PIDFile=/opt/atlassian/confluence-%I/work/catalina.pid

[Install]
WantedBy=multi-user.target

即使使用此版本,我也不确定PIDFile声明会发生什么,也不太确定如何使用包装脚本补偿(如果需要)。我扫描过的文档似乎暗示systemd相当擅长了解PID,因此可能不需要。但是,只有测试才能证明最终效果。

答案 1 :(得分:-1)

每个实例都没有单独的启动/停止脚本。

我建议ExecStart=/opt/atlassian/confluence/bin/start-confluence.sh

这将在每次调用时启动一个新实例。

同样适用于ExecStartPreExecStop