我的 nginx 单元文件如下,
[root@arif ~]# cat /usr/lib/systemd/system/nginx.service
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/run/nginx.pid
# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
# SELinux context. This might happen when running `nginx -t` from the cmdline.
# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
ExecStartPre=/usr/bin/rm -f /run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true
[Install]
WantedBy=multi-user.target
这里,在该[Service]
部分中,的值Type
等于forking
从这里开始的意思,
以 ExecStart 启动的进程会生成一个子进程,该子进程将成为服务的主进程。启动完成后父进程退出。
我的问题是,
- 为什么服务会这样做?
- 这样做有什么好处?
- 出了什么问题
Type=simple
或其他类似的选择?
事实上,服务通常不会那样做。除了这不是一个好的做法,而且“dæmonization”的想法确实是错误的之外,服务所做的并不是
forking
协议所要求的。他们弄错了协议,因为他们实际上是在做其他事情forking
,这通常是不必要地被硬塞到协议中的。没有。存在更好的准备通知协议,实际上没有人正确地使用该协议。这个服务单位没有这样做,因为它是有利的。
没有什么。事实上,通常是使用
forking
准备协议是错误的。正如其他答案所声称的那样,这不是最佳实践。恰恰相反。一个简单的事实是,这是一个糟糕的工作中最好的一个,它可以应对仍然无法关闭的 nginx 行为。现在的大多数服务软件,多亏了 IBM SRC、daemontools 和其他严肃的服务管理领域的 25 年的鼓励,已经获得了选项,甚至改变了它们的默认行为,而不是试图愚蠢地“dæmonize”某些东西已经在 dæmon context 中。
但是,对于 nginx,情况仍然不是这样。
daemon off
不工作,可悲的是。就像许多软件错误地将“non-dæmonize”模式与调试模式混为一谈一样(但现在通常不再这样做),nginx 不幸地将其与其他事情混为一谈,例如不处理其控制信号。到目前为止,人们已经为此努力了 5 年。进一步阅读
type=forking
在 systemd 服务文件中使用。Debian 错误 #728015。只要有问题的服务在完成初始化后不特别支持消息传递 systemd(请参阅
man systemd-notify
参考资料),就会使用分叉方法作为传统的通知方式:只要父进程存在,则报告的服务状态systemctl status
保持在start
.它
running
仅在父进程退出后更改。传统守护程序服务的父进程只有在子进程完成设置并准备好使用后才会退出。如果有任何依赖服务等待相关服务准备好使用,则需要此机制。如果不使用传统的守护进程分叉机制,是否会启动不支持
systemd
特定通知方法的服务,服务状态变为running
立即,并且在相关服务之后立即启动任何依赖服务,然后才可以使用。这个原因在Debian Bug #728015中有更详细的解释,该错误已在 JdeBP 的答案中链接。
这个原因也是那个bug被关闭的原因
wontfix
。