我是 Apache 的新手,正在调试由它引起的问题。我了解到,当 Apache 启动时,它会httpd.pid
以人类可读的格式写入自己的进程 ID,如所述这里。
我不太明白为什么首先需要进程 ID。即使需要,我也不明白这种方法的原因。
在Linux上,进程可以使用ps -ef
和等来找到Apache的进程ID。一般来说,我还没有听说其他进程将其进程ID写入某个文件中。
这个 Apache 进程有何特别之处?
答案1
在大多数 Unix 系统上,服务由在里面系统。许多 Linux 发行版使用传统的系统初始化,它几乎完全缺乏服务管理功能,因此启动或终止 Apache 的实际工作由脚本/etc/init.d
完成/etc/rc.d
。这些启动脚本用普通话写成什并且没有其他方法来跟踪它们启动的进程——除了从预设位置读取其 PID。(启动脚本只能知道它直接启动的进程的 PID,但不知道其子进程的 PID)那些进程,也不是上次调用同一脚本时启动的进程。这意味着 initscript 无法跟踪被编程为“守护”自身的进程。)
ps -ef
(是的,可以使用或直接检查来找到进程/proc
。但是,这是一种不太可靠的方法——可能同时运行多个 Apache 进程:例如,mpm-prefork,或多个独立的 Apache 配置。因此,几乎每个守护进程/run
在 Linux 上,将在或中创建一个“pidfile” /var/run
,以便可以通过 initscript 轻松停止它。您可能会有crond.pid
、ntpd.pid
、rsyslogd.pid
、sshd.pid
等等。)
只有最近的 Linux init 系统才会费心跟踪进程:暴发户在 Ubuntu 中,必须明确告知预期的 fork 数量,而systemdFedora 使用内核cgroups跟踪属于某个服务的进程。
答案2
原因是第三方可以使用信号,通过kill(1)
,以控制正在运行的 Apache 实例。例如,指示它正常地重新加载配置。
其他答案仍然适用。
还要记住,您可以在同一台机器上的不同端口和不同配置上运行多个 Apache 实例。当您使用(默认,IIRC)分叉模式时,情况会变得更加有趣。您需要能够找出一些子进程的控制实例,所以这是最实用的方法。
答案3
Apache 想知道另一个 Apache 实例是否已在运行。写入进程号比使用更可靠ps
,它允许测试进程是否意外关闭(不删除.pid
文件)。也不能保证ps
在任何特定系统上都可用(例如由于权限原因)。
许多其他程序也使用.pid
文件。检查您的/var/run
目录。我的目录中有几个。
答案4
正如其他答案所说,您需要有进程 ID 来向其发送信号。由于它是一个守护进程,因此信号是主要的通信方法之一。您可以使用信号结束 apache、告诉它重新加载配置等。
对于 Apache 和进程模型来说,这一点更为重要,因为(通常)Apache 具有父/子关系,父节点是分叉/收获子节点的控制器。如果要关闭服务器,您需要向父节点发送信号,而不是向子节点发送信号。如果您这样做,ps
您必须仔细研究这种父/子关系才能找到父节点;只有这样,您才能向它发送信号。