Httpd 重启“地址已被使用”错误

Httpd 重启“地址已被使用”错误

我有一个自己创建的 .rpm。在其中%post,我做了一些事情,并在此脚本的末尾调用了service httpd restart。它给出了以下错误:

+ service httpd restart
Stopping httpd: [FAILED]
Starting httpd: (98)Address already in use: make_sock: could not bind to address [::]:81
(98)Address already in use: make_sock: could not bind to address 0.0.0.0:81
no listening sockets available, shutting down
Unable to open logs
[FAILED]

我从 rpm 详细安装 (-vv) 中得到这个信息。所以我知道这是关于 httpd 本身的重启,而不是其他。根据 netstat,只有一个进程 (httpd) 正在监听端口 81。

$ sudo netstat -nlp | grep 81
tcp      0      0 :::81        :::*      LISTEN      29670/httpd

我不明白,为什么运行 http 在停止时会失败,而在启动时会再次失败。

有什么想法可以解决这个问题吗?

答案1

根据实现而定的 init.d 脚本(由服务命令调用)并不像您想象的那么智能。我在许多此类实现中看到,“start”的执行会隐藏原始 httpd 进程(即以 root 身份运行的进程)的进程号。然后,当您执行“stop”进程时,它只是终止(使用适当的信号号)root httpd 进程。

有时,从属进程会变成孤儿进程,而不会被终止(因为它们可能已损坏,无法正确响应父进程的信号)。如果是这种情况,则端口仍由从属进程连接,执行“重新启动”或“启动”将失败。

您需要做的是执行“ ps -aef | grep httpd | grep -v grep”来查找损坏的从属进程,然后直接将其终止(使用kill -9 pid#)。损坏的进程可能不止一个。

一旦所有损坏的进程都被终止,您就可以再次“启动” apache 服务器。

答案2

这是有时这表明主机已受到攻击或正在运行行为不当的进程。我说已受到攻击是因为许多恶意软件会分叉到后台并忽略信号。但是它们通常不会关闭分叉时存在的打开的文件描述符。

这会导致恶意软件继承 apache 保持打开的套接字,从而忽略完成信号。这会导致“无法绑定到地址”问题。

尝试发出命令pgrep -l -u apache并查看是否出现任何非 apache 的进程。

相关内容