为什么systemd启动后立即停止服务?

Nan*_*ani 5 systemd

我有一个基于 C++ 的应用程序,我正在运行(可执行)作为 systemd 的守护进程。

单元文件:

[单元]
说明=控制台服务
之后=网络.目标

[服务]
Environment="USER=ubuntu" "路径=/home/ubuntu/console/bin" 
WorkingDirectory=/home/ubuntu/console/bin
ExecStart=/bin/sh -ec "exec /sbin/start-stop-daemon -S -c ${USER} -d ${Path} --pidfile=/var/run/console.pid --oknodo --exec控制台可执行文件“#2>/dev/null
ExecStop=/bin/sh -ec "exec /sbin/start-stop-daemon -K --quiet -c ${USER} -d ${Path} --pidfile=/var/run/console.pid --retry =TERM/30/KILL/5 --oknodo --exec consoleExecutable" #2>/dev/null
重启=失败
RemainAfterExit=no
超时停止秒=10
成功退出状态=0 1
TimeoutStartSec=360

[安装]
WantedBy=multi-user.target

当我发出 start 命令时,服务正在启动,但它立即收到关闭信号然后退出。任何线索,发生了什么?

须藤 systemctl 状态 console.service
? console.service - 控制台服务
   已加载:已加载(/etc/systemd/system/console.service;已启用;供应商预设:已启用)
   活动:自 UTC 时间周一 2017-09-25 19:58:58 起停用(stop-sigterm);1 秒前
  进程:8706 ExecStop=/bin/sh -ec exec /sbin/start-stop-daemon -K --quiet -c ${USER} -d ${Path} --pidfile=/var/run/console.pid - -retry=TERM/30/KILL/5 --oknodo --exec consoleExecutable #2>/dev/null (code=exited, status=0/SUCCESS)
  进程:8701 ExecStart=/bin/sh -ec exec /sbin/start-stop-daemon -S -c ${USER} -d ${Path} --pidfile=/var/run/console.pid --oknodo - -exec consoleExecutable #2>/dev/null (code=exited, status=0/SUCCESS)
 主PID:8701(代码=退出,状态=0/成功)
    任务:1
   内存:1.8M
      CPU:53ms
   C组:/system.slice/console.service
           ??8705 控制台可执行文件

9 月 25 日 19:58:58 mgmt1 systemd[1]:启动控制台服务。

须藤 systemctl 状态 console.service
? console.service - 控制台服务
   已加载:已加载(/etc/systemd/system/console.service;已启用;供应商预设:已启用)
   活动:自 2017-09-25 星期一 UTC 时间 19:59:01 起不活动(死亡);947 毫秒前
  进程:8706 ExecStop=/bin/sh -ec exec /sbin/start-stop-daemon -K --quiet -c ${USER} -d ${Path} --pidfile=/var/run/console.pid - -retry=TERM/30/KILL/5 --oknodo --exec consoleExecutable #2>/dev/null (code=exited, status=0/SUCCESS)
  进程:8701 ExecStart=/bin/sh -ec exec /sbin/start-stop-daemon -S -c ${USER} -d ${Path} --pidfile=/var/run/console.pid --oknodo - -exec consoleExecutable #2>/dev/null (code=exited, status=0/SUCCESS)
 主PID:8701(代码=退出,状态=0/成功)

9 月 25 日 19:58:58 mgmt1 systemd[1]:启动控制台服务。

Jde*_*eBP 11

Environment="USER=ubuntu" "路径=/home/ubuntu/console/bin" 
WorkingDirectory=/home/ubuntu/console/bin
ExecStart=/bin/sh -ec "exec /sbin/start-stop-daemon -S -c ${USER} -d ${Path} --pidfile=/var/run/console.pid --oknodo --exec控制台可执行文件“#2>/dev/null
ExecStop=/bin/sh -ec "exec /sbin/start-stop-daemon -K --quiet -c ${USER} -d ${Path} --pidfile=/var/run/console.pid --retry =TERM/30/KILL/5 --oknodo --exec consoleExecutable" #2>/dev/null

这几乎配得上系统化的恐怖屋。如果不是那里已经有一个恐怖故事可以做到这一点。

不要start-stop-daemon在一个服务单元中使用它来完成一个服务单元已经做的所有事情。有了不必要的 PID 文件和ExecStart接受 shell 语法注释的错误假设,同样如此。

并且不要做其他答案所说的并尝试用Type=forking. 这让事情变得更糟,而不是更好。

废话start-stop-daemon是为什么事情会出错。因为正在运行的进程start-stop-daemon并没有成为服务,但实际上几乎立即退出,systemd 认为您的服务正在终止。在您的第一个systemctl status输出中,您可以看到 systemd 正在发送SIGTERM以清除所有运行ExecStop操作后剩余的正在运行的进程,这就是它认为服务已终止时所做的事情。

只做简单的事情:

类型=简单
WorkingDirectory=/home/ubuntu/console/bin
用户=ubuntu
ExecStart=/home/ubuntu/console/bin/consoleExecutable

不需要ExecStop也不Environment需要。

进一步阅读


小智 6

systemd 认为你的守护进程的 pid 是 8701,它是start-stop-daemon. 你的守护进程的 pid 是 8705。你需要在你的单元文件中设置Type=forking(under [Service])。默认是Type=simple假设进程不分叉。

但是,你为什么要使用这个/bin/sh -ec exec /sbin/start-stop-daemon怪物?systemd 可以处理 start-stop-daemon 所做的一切。