为什么在服务的单元文件中使用分叉?

ari*_*rif 4 linux fork systemd

我的 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
Run Code Online (Sandbox Code Playgroud)

在这里,在该[Service]部分中,的值Type等于forking这意味着从这里开始

以 ExecStart 启动的进程会生成一个子进程,该子进程成为服务的主进程。启动完成后,父进程退出。

我的问题是,

  • 为什么服务会这样做?
  • 这样做有什么好处?
  • 有什么问题Type=simple或其他类似的选择?

Jde*_*eBP 6

为什么服务会这样做?

事实上,服务通常会这样做。除了这不是一个好的做法,“dæmonization”的想法确实是错误的,服务所做的并不是forking协议所要求的。他们弄错了协议,因为他们实际上正在做其他事情,而这些事情forking通常是不必要的。

这样做有什么好处?

没有。存在更好的就绪通知协议,但实际上没有人正确使用协议。这个服务单位不这样做是因为它是有利的。

有什么问题Type=simple或其他类似的选择?

没有。实际上,通常forking错误的是准备协议的使用。正如其他答案中所述,这不是最佳实践。恰恰相反。

一个简单的事实是,这是一个糟糕的工作中最好的一个,一个解决仍然无法关闭的 nginx 行为的工具。由于 IBM SRC、daemontools 和其他严肃的服务管理领域 25 年来的鼓励,如今的大多数服务软件已经获得了选项,甚至改变了它们的默认行为,不再试图愚蠢地“dæmonize”某些东西已经在守护进程上下文中

但是,对于 nginx 来说情况仍然不是这样。 daemon off不工作,可悲。正如许多软件过去错误地将“非dæmonize”模式与调试模式混为一谈(但现在通常不再这样做),nginx 不幸地将其与其他东西混为一谈,例如不处理其控制信号。到目前为止,人们已经为此努力了 5 年。

进一步阅读