我有一个二进制文件,没有任何内置命令来重新启动或关闭它创建的进程。在查看了一些内置的 CentOS 服务后,我得出的结论是我不能将它们用作模板,因为它们中的很多都尊重便捷性SIGHUP
等。这意味着我需要创建 .sh 脚本来运行和控制它,这就是我遇到的一些问题。单元模板有一个叫做PID文件但我在文档中找不到任何信息如果 systemd 管理并跟踪PID
它启动的进程,或者它只是指出PID file
服务将自行创建的一种方式。如果它是第一个,那么如果它是通过 /bin/sh 而不是二进制文件本身执行的脚本,它将如何正确跟踪它?难道它不会捕获 的sh process
PID 吗?
查看 HTTPD (Apache) 服务单元:
[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
Documentation=man:httpd(8)
Documentation=man:apachectl(8)
[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/httpd
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
ExecStop=/bin/kill -WINCH ${MAINPID}
如果 ${MAINPID} 没有在任何地方声明,他们如何在这里引用它?
我当前的假设是我必须传递给我的 .sh 脚本参数来处理启动/停止/终止重新启动操作。这是普遍接受的做法吗?如果我要以有限用户身份运行它(这是一个我根本不敢碰的页面),那么它如何与 SElinux 一起工作 - sh 脚本也会以指定的有限用户身份运行吗?
答案1
我当前的假设是我必须传递给我的 .sh 脚本参数来处理启动/停止/终止重新启动操作。
这是一种常见的做法。这是一个常见的坏的实践。它是一个穷人的守护进程,用 shell 脚本写得很糟糕(一如既往)。这是完全没有必要的。事实上,您所询问的几乎所有内容都是完全不必要的。不要使用“Poor Man's Dæmon Supervisors”和“Bad Loggers”编写包装 shell 脚本。不要乱搞不稳定且危险的 PID 文件机制。您正在使用服务管理器,并且它不需要任何这些。
设立Type=simple
服务单位。你可以systemctl
用start
, stop
, restart
, reload
, enable
, 和disable
完全可以使用没有愚蠢的包装脚本。像 systemd 等服务管理器只记得进程 ID,因为它首先分叉了它。
如果你的程序有一些“守护进程”机制,把它关掉和不要使用它。感谢 daemontools 等人。在很长一段时间以来,这一直是一个要求,许多程序在过去 20 多年里已经发展了这样的机制,而其他程序则根本不首先默认为“守护进程”,因此可以在其默认操作模式中使用。
切勿使用Type=forking
.这应该是绝望中的最后手段,因为几乎没有程序实际上讲协议。你的程序无疑不会。选择Type=simple
为标准。使用早期套接字打开(使用套接字单元配置),或者Type=notify
,如果程序支持它们。回到程序的作者那里,LISTEN_FDS
如果不支持的话,鼓励支持早期套接字打开(协议),并且它是一个侦听套接字连接的程序。ExecStop
如果TERM
信号停止你的程序,不要使用任何显式的,它应该。不用担心${MAINPID}
,您的单元文件中不会有它。
看在上帝的份上,不要把 Apache 作为一个供新手复制的简单而直接的服务示例。 Apache 认为WINCH
应该终止进程。找点别的东西看看。
进一步阅读
- 乔纳森·德博因·波拉德 (2001)。 设计 Unix 守护程序时要避免的错误。常见答案。
- 乔纳森·德博因·波拉德 (2015)。您确实不需要守护进程。真的。。 systemd 恐怖屋。
- 乔纳森·德博因·波拉德 (2015)。Unix 守护进程的就绪协议问题。经常给出的答案。