Apache网络错误AH00072:make sock:无法绑定到地址

来自菜鸟教程
跳转至:导航、​搜索

介绍

当有另一个进程在 Apache 配置为使用的同一端口上侦听时,会生成 Apache AH00072: make_sock: could not bind to address 错误消息。 通常,该端口将是用于 HTTP 连接的标准端口 80,或用于 HTTPS 连接的端口 443。 但是,与其他进程的任何端口冲突都可能导致 AH00072 错误。

该错误源自底层操作系统系统的网络堆栈。 问题是在任何给定时间只能将一个进程绑定到端口。 如果另一个 Web 服务器(如 Nginx)被配置为侦听端口 80 并且它正在运行,那么 Apache 将无法为自己声明该端口。

要检测与 Apache 的端口冲突,您需要检查 systemctljournalctl 输出以确定导致错误的 IP 地址和端口。 然后,您可以决定如何解决问题,无论是通过切换 Web 服务器、更改 Apache 使用的 IP 地址、端口还是这些选项的任意组合。

systemctl 故障排除

按照本系列开头的 如何对常见 Apache 错误进行故障排除 教程中的故障排除步骤,当您对 AH00072: make_sock: could not bind to address 错误消息进行故障排除时,第一步是使用 systemctl

如果 systemctl 不包含描述问题的输出,那么本教程的最后一部分 使用 journalctl 日志进行故障排除 说明如何检查 systemd 日志以找到冲突的港口。

systemctl status 的输出在许多情况下将包含解决错误所需的所有诊断信息。 它将包括 Apache 正在使用的 IP 地址,以及它尝试绑定到的端口。 输出还将指示 Apache 无法启动多长时间,以便您可以确定问题影响 Apache 的时间。

在 Ubuntu 和 Debian 派生的 Linux 发行版上,运行以下命令来检查 Apache 的状态:

Ubuntu 和 Debian 系统

sudo systemctl status apache2.service -l --no-pager

在 CentOS 和 Fedora 系统上,使用以下命令检查 Apache 的状态:

CentOS 和 Fedora 系统

sudo systemctl status httpd.service -l --no-pager

-l 标志将确保 systemctl 输出一行的全部内容,而不是用省略号 () 代替长行。 --no-pager 标志会将整个日志输出到您的屏幕,而无需调用像 less 这样一次只显示一个屏幕内容的工具。

由于您正在对 AH00072: make_sock 错误消息进行故障排除,因此您应该会收到类似于以下内容的输出:

Output● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since Tue 2020-07-28 13:58:40 UTC; 8s ago
     Docs: man:httpd.service(8)
  Process: 69 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)
Main PID: 69 (code=exited, status=1/FAILURE)
   Status: "Reading configuration..."
     Tasks: 213 (limit: 205060)
   Memory: 25.9M
   CGroup: /system.slice/containerd.service/system.slice/httpd.service

Jul 28 13:58:40 e3633cbfc65e systemd[1]: Starting The Apache HTTP Server…
Jul 28 13:58:40 e3633cbfc65e httpd[69]: (98)Address already in use: AH00072: make_sock: could not bind to address [::]:80
Jul 28 13:58:40 e3633cbfc65e httpd[69]: (98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:80
Jul 28 13:58:40 e3633cbfc65e httpd[69]: no listening sockets available, shutting down
Jul 28 13:58:40 e3633cbfc65e httpd[69]: AH00015: Unable to open logs
Jul 28 13:58:40 e3633cbfc65e systemd[1]: httpd.service: Main process exited, code=exited, status=1/FAILURE
Jul 28 13:58:40 e3633cbfc65e systemd[1]: httpd.service: Failed with result 'exit-code'.
Jul 28 13:58:40 e3633cbfc65e systemd[1]: Failed to start The Apache HTTP Server.

请注意,如果您使用的是 Ubuntu 或 Debian 派生发行版,其中 Apache 进程的名称不是 httpd 而是 apache2,您的输出可能会略有不同。

此示例 systemctl 输出包括来自 systemd 日志的一些突出显示的行,这些行描述了 AH00072 错误。 这两行都以 (98)Address already in use: AH00072: make_sock: could not bind to address 开头,为您提供有关 AH00072 错误的所有信息,您需要进一步解决它,因此您可以跳过以下 journalctl 步骤,而是继续本教程末尾的 ss 和 ps 实用程序 部分的故障排除。

如果您的 systemctl 输出未提供有关导致 AH00072 错误的 IP 地址和端口的特定信息,您将需要检查 systemd 日志中的 journalctl 输出. 以下部分说明如何使用 journalctl 对 AH00072 错误进行故障排除。

使用 journalctl 日志进行故障排除

如果您的 systemctl 输出不包含有关 AH00072 错误的详细信息,则应继续使用 journalctl 命令检查 Apache 的 systemd 日志。

在 Ubuntu 和 Debian 派生系统上,运行以下命令:

sudo journalctl -u apache2.service --since today --no-pager

在 CentOS、Fedora 和 RedHat 派生系统上,使用以下命令检查日志:

sudo journalctl -u httpd.service --since today --no-pager

--since today 标志将限制命令的输出以仅记录从当天 00:00:00 开始的条目。 使用此选项将有助于限制检查错误时需要检查的日志条目的数量。

如果 Apache 无法绑定到正在使用的端口,请在输出中搜索与以下日志条目类似的行,特别是包含本示例中突出显示的 AH00072 错误代码的行:

Output-- Logs begin at Tue 2020-07-14 20:10:37 UTC, end at Tue 2020-07-28 14:01:40 UTC. --
. . .
Jul 28 14:03:01 b06f9c91975d apachectl[71]: (98)Address already in use: AH00072: make_sock: could not bind to address [::]:80
Jul 28 14:03:01 b06f9c91975d apachectl[71]: (98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:80
Jul 28 14:03:01 b06f9c91975d apachectl[71]: no listening sockets available, shutting down

此输出指示两个 AH00072 错误。 其中第一个解释了 Apache 无法绑定到 [::]:80 地址,即所有可用 IPv6 接口上的端口 80。 下一行,地址为 0.0.0.0:80,表示 Apache 无法绑定到所有可用 IPv4 接口上的端口 80。 根据您的系统配置,IP 地址可能不同且仅显示单个 IP,并且可能仅包含 IPv4 或 IPv6 错误。

即使您自己的系统可能有不同的冲突接口和端口,错误也会与此处显示的输出类似。 通过 journalctl 的输出,您将能够在本教程的以下部分中使用 ss 诊断问题。

使用 ssps 实用程序进行故障排除

要解决 AH00072 错误,您需要确定其他进程正在侦听 Apache 尝试使用的 IP 地址和端口。 大多数现代 Linux 发行版都包含一个名为 ss 的实用程序,可用于收集有关系统网络套接字状态的信息。

在前面的 journalctl 部分中,某些内容已经绑定到端口 80 上的 IPv4 和 IPv6 地址。 以下命令将确定已绑定到端口 80 上的 IPv4 接口的进程的名称。 如果它与以下命令中的 80 不同,请确保从错误消息中替换端口:

sudo ss -4 -tlnp | grep 80

ss 命令的标志以下列方式改变其默认输出:

  • -4 限制 ss 只显示 IPv4 相关的套接字信息。
  • -t 将输出限制为仅 tcp 套接字。
  • -l 显示考虑了 -4-t 限制的所有侦听套接字。
  • -n 确保显示端口号,而不是像“httporhttps”这样的协议名称。 这很重要,因为 Apache 可能会尝试绑定到非标准端口,并且与实际端口号相反,服务名称可能会令人困惑。
  • -p 输出有关绑定到端口的进程的信息。

使用所有这些标志,您将收到如下输出:

OutputLISTEN   0         511                 0.0.0.0:80               0.0.0.0:*        users:(("nginx",pid=40,fd=6))

在排除 AH00072 错误时,前三个字段并不重要,因此可以忽略它们。 重要的字段是第四个 (0.0.0.0:80),它匹配您之前发现的 journalctl 错误,以及最后一个 users:(("nginx",pid=40,fd=6)),特别是 pid=40 部分.

如果您遇到与 IPv6 接口相关的 AH00072 错误,请重复 ss 调用,这次使用 -6 标志将接口限制为 IPv6 网络堆栈,如下所示:

sudo ss -6 -tlnp |grep 80
OutputLISTEN   0         511                    [::]:80                  [::]:*        users:(("nginx",pid=40,fd=7))

如果与此处给出的突出显示的 80 不同,请再次从 journalctl 输出中替换有问题的端口号。

在 IPv4 和 IPv6 错误的这两种情况下,ss 输出表明有一个进程 ID 为 40 的程序(输出中的 pid=40)绑定到 [X174X ] 和 [::]:80 接口。 此过程阻止 Apache 启动,因为它已经拥有该端口。 要确定程序的名称,请像这样使用 ps 实用程序,用输出中的进程 ID 代替此示例中突出显示的 40 值:

sudo ps -p 40

您将收到类似于以下内容的输出:

OutputPID TTY          TIME CMD
40 ?        00:00:00 nginx

输出中突出显示的 nginx 是正在侦听接口的进程的名称。 现在您有了阻止 Apache 启动的程序的名称,您可以决定如何解决该错误。 您可以停止 nginx 进程,重新配置 nginx 以侦听不同的接口和端口,或重新配置 Apache 以避免端口冲突。

请务必注意,如果您正在诊断 AH00072 错误,则该过程可能与 nginx 不同,并且端口和 IP 地址可能并不总是 0.0.0.0[::]。 通常,不同的 Web 服务器和代理将在同一台服务器上使用。 每个都可能试图绑定到不同的 IPv4 端口和 IPv6 接口以处理不同的 Web 流量。 例如,配置了 HAProxy 的服务器在端口 8080 上侦听 IPv4 环回地址(也称为 localhost)将显示 ss 输出,如下所示:

OutputLISTEN   0         2000              127.0.0.1:8080            0.0.0.0:*       users:(("haproxy",pid=545,fd=7))

将指示特定 IP 地址和端口的 systemctl 输出或 journalctl 输出与来自 ss 的诊断数据组合起来很重要,然后是 ps 以缩小范围关闭导致 Apache 无法启动的进程。

结论

在本教程中,您学习了如何对 IPv4 和 IPv6 接口上的 Apache AH00072 make_sock: could not bind to address 错误消息进行故障排除。 您学习了如何使用 systemctl 检查 Apache 服务器的状态并尝试查找错误消息。 您还学习了如何使用 journalctl 检查 systemd 日志以获取有关 AH00072 错误的特定信息。

通过日志中的相应错误消息,您随后了解了 ss 实用程序以及如何使用它来检查系统网络套接字的状态。 之后,您学习了如何将 ss 中的进程 ID 信息与 ps 实用程序结合起来,以查找导致 Apache 无法启动的进程的名称。