我有一个 openSUSE 13.1 VM(主机运行 Virtualbox 4.2.18,也在 openSUSE 13.1 上)并且重新启动 httpd(Apache/2.4.6)总是需要 1.5 分钟:
foobar:~ # time /etc/init.d/apache2 restart
redirecting to systemctl restart apache2.service
real 1m30.778s
user 0m0.004s
sys 0m0.000s
立即随后重新启动是正常的(非常快):
foobar:~ # time /etc/init.d/apache2 restart
redirecting to systemctl restart apache2.service
real 0m1.023s
user 0m0.004s
sys 0m0.000s
5 分钟后,重新启动时间再次精确到 90 秒:
foobar:/tmp # time /etc/init.d/apache2 restart
redirecting to systemctl restart apache2.service
real 1m30.684s
user 0m0.000s
sys 0m0.000s
到目前为止我一直在寻找什么:
top
虽然 apache 正在重新启动并没有显示很多(~0% 的使用率)。netstat
也没有显示出与外界的任何联系。
请注意,这是一个当前流量为 0 且内存和磁盘中有大量可用 GB 的 VM。
我还发现“重启”的“停止”部分需要 90 秒。
知道为什么会发生这种情况,或者我接下来应该在哪里看?
编辑:我发现当stop
需要 90 秒时,我始终会得到以下内容/var/log/apache2/error_log
:
[core:notice] [pid 3179] AH00052: child pid 3203 exit signal Segmentation fault (11)
经过大量的试验和错误,我发现它是由
php5
正在加载的模块引起的/etc/sysconfig/apache2
。删除它完全停止了这种行为。不过我需要这个
php5
模块,所以为了减轻这种延迟,我在中添加了以下内容etc/apache2/server-tuning.conf
:现在,当停止 apache 时发生段错误时,它只会挂起 2 秒。
同样的事情发生在我身上,结果我将 /etc/hosts 文件保留为默认设置。
在我更新了类似这样的主机文件后,延迟立即消失了:
参考:
服务多个域的单个 IP 服务器的 /etc/hosts 条目
https://unix.stackexchange.com/questions/57439/slow-start-of-midnight-commander#answer-397879
使用优雅重启时,父 apache 进程停止接受新连接并永远等待所有子进程退出。所以基本上网络服务器已经死了(除了现有的连接),直到所有现有的孩子都退出。
在短期 http/https 连接的正常用例中,在正常关闭或重新启动时这不是问题……通常需要一秒钟。问题是当你有一些东西会延迟孩子退出时,比如持久的 websocket 连接。在这种情况下,服务器将永远无法真正优雅地停止/重新启动......它将永远处于半死状态。
您可以使用 GracefulShutdownTimeout 指令调整延迟:
https://httpd.apache.org/docs/2.4/mod/mpm_common.html#gracefulshutdowntimeout
默认情况下,它设置为 0(无限)。5 秒是一个更合理的值。
请注意,当使用 systemctl 重新启动服务器时,默认情况下它只会等待最多 90 秒,然后才会强制它杀死子进程(而不是永远),这就是您看到这个 90 秒延迟的原因。这是在 /etc/systemd/system.conf 中设置的:
这也可以使用 TimeoutStopSec 选项为单个单元更改。