Apache2 在正常运行 8-12 天后卡住了。没有错误。卡在空循环和 Recv-Q 中

Apache2 在正常运行 8-12 天后卡住了。没有错误。卡在空循环和 Recv-Q 中

我有一些新的 Web 服务器,其中运行着 ubuntu 22 LTS、apache2 和 php-fpm,以及 mpm_event。

它们的表现都一样。apache 运行 8-12 天后。它突然停止接收请求,直到我手动重新启动 apache2。然后它又正常运行了 10 天。

它会随机崩溃

这是 netstat 的输出 Apache 似乎只监听 tcp6? 好像不对。。它不应该监听普通的 tcp 吗?

netstat -tulpn

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      729/systemd-resolve 
tcp        0      0 0.0.0.0:22825           0.0.0.0:*               LISTEN      2728/php            
tcp        0      0 0.0.0.0:23004           0.0.0.0:*               LISTEN      2752/php            
tcp        0      0 0.0.0.0:22928           0.0.0.0:*               LISTEN      2742/php            
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1072/sshd: /usr/sbi 
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      971/mysqld          
tcp        0      0 127.0.0.1:33060         0.0.0.0:*               LISTEN      971/mysqld          
tcp6       0      0 :::9100                 :::*                    LISTEN      1074312/node_export 
tcp6      71      0 :::80                   :::*                    LISTEN      2207/apache2        
tcp6       0      0 :::22                   :::*                    LISTEN      1072/sshd: /usr/sbi 
tcp6     512      0 :::443                  :::*                    LISTEN      2207/apache2        
udp        0      0 127.0.0.53:53           0.0.0.0:*                           729/systemd-resolve 
udp        0      0 0.0.0.0:500             0.0.0.0:*                           1073/charon         
udp        0      0 0.0.0.0:4500            0.0.0.0:*                           1073/charon         
udp6       0      0 :::500                  :::*                                1073/charon         
udp6       0      0 :::4500                 :::*                                1073/charon

我也做了堆栈跟踪。

strace -o apache.strace -f -p 2207

输出:

2207  times({tms_utime=3026 /* 30.26 s */, tms_stime=6010 /* 60.10 s */, tms_cutime=369020 /* 3690.20 s */, tms_cstime=174724 /* 1747.24 s */}) = 1819843146
2207  pselect6(0, NULL, NULL, NULL, {tv_sec=1, tv_nsec=0}, NULL) = 0 (Timeout)
2207  wait4(-1, 0x7ffedc77b084, WNOHANG|WSTOPPED, NULL) = 0
2207  times({tms_utime=3026 /* 30.26 s */, tms_stime=6010 /* 60.10 s */, tms_cutime=369020 /* 3690.20 s */, tms_cstime=174724 /* 1747.24 s */}) = 1819843246
2207  pselect6(0, NULL, NULL, NULL, {tv_sec=1, tv_nsec=0}, NULL) = 0 (Timeout)
2207  wait4(-1, 0x7ffedc77b084, WNOHANG|WSTOPPED, NULL) = 0
2207  times({tms_utime=3026 /* 30.26 s */, tms_stime=6010 /* 60.10 s */, tms_cutime=369020 /* 3690.20 s */, tms_cstime=174724 /* 1747.24 s */}) = 1819843346
2207  pselect6(0, NULL, NULL, NULL, {tv_sec=1, tv_nsec=0}, NULL) = 0 (Timeout)
2207  wait4(-1, 0x7ffedc77b084, WNOHANG|WSTOPPED, NULL) = 0
2207  times({tms_utime=3026 /* 30.26 s */, tms_stime=6010 /* 60.10 s */, tms_cutime=369020 /* 3690.20 s */, tms_cstime=174724 /* 1747.24 s */}) = 1819843446
2207  pselect6(0, NULL, NULL, NULL, {tv_sec=1, tv_nsec=0}, NULL) = 0 (Timeout)
2207  wait4(-1, 0x7ffedc77b084, WNOHANG|WSTOPPED, NULL) = 0
2207  times({tms_utime=3026 /* 30.26 s */, tms_stime=6010 /* 60.10 s */, tms_cutime=369020 /* 3690.20 s */, tms_cstime=174724 /* 1747.24 s */}) = 1819843546
2207  pselect6(0, NULL, NULL, NULL, {tv_sec=1, tv_nsec=0}, NULL) = 0 (Timeout)
2207  wait4(-1, 0x7ffedc77b084, WNOHANG|WSTOPPED, NULL) = 0
2207  times({tms_utime=3026 /* 30.26 s */, tms_stime=6010 /* 60.10 s */, tms_cutime=369020 /* 3690.20 s */, tms_cstime=174724 /* 1747.24 s */}) = 1819843646
2207  pselect6(0, NULL, NULL, NULL, {tv_sec=1, tv_nsec=0}, NULL) = 0 (Timeout)
2207  wait4(-1, 0x7ffedc77b084, WNOHANG|WSTOPPED, NULL) = 0
2207  times({tms_utime=3026 /* 30.26 s */, tms_stime=6010 /* 60.10 s */, tms_cutime=369020 /* 3690.20 s */, tms_cstime=174724 /* 1747.24 s */}) = 1819843747
2207  pselect6(0, NULL, NULL, NULL, {tv_sec=1, tv_nsec=0}, NULL) = 0 (Timeout)
2207  wait4(-1, 0x7ffedc77b084, WNOHANG|WSTOPPED, NULL) = 0
2207  times({tms_utime=3026 /* 30.26 s */, tms_stime=6010 /* 60.10 s */, tms_cutime=369020 /* 3690.20 s */, tms_cstime=174724 /* 1747.24 s */}) = 1819843847
2207  pselect6(0, NULL, NULL, NULL, {tv_sec=1, tv_nsec=0}, NULL) = 0 (Timeout)
2207  wait4(-1, 0x7ffedc77b084, WNOHANG|WSTOPPED, NULL) = 0
2207  times({tms_utime=3026 /* 30.26 s */, tms_stime=6010 /* 60.10 s */, tms_cutime=369020 /* 3690.20 s */, tms_cstime=174724 /* 1747.24 s */}) = 1819843947
2207  pselect6(0, NULL, NULL, NULL, {tv_sec=1, tv_nsec=0}, NULL) = 0 (Timeout)
2207  wait4(-1, 0x7ffedc77b084, WNOHANG|WSTOPPED, NULL) = 0

它就这样永远循环下去。

这是 iptables 设置

-P INPUT DROP
-P FORWARD DROP
-P OUTPUT ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -i eth0 -p tcp -m multiport --dports 22345:25000 -m conntrack --ctstate NEW -j ACCEPT

ip6tables:

-P INPUT DROP
-P FORWARD DROP
-P OUTPUT ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p ipv6-icmp -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -i eth0 -p tcp -m multiport --dports 22345:25000 -m conntrack --ctstate NEW -j ACCEPT

答案1

这是 PHP 堆栈中工作线程耗尽的典型症状。这通常意味着通过模块运行 php 的 Apache 工作线程在等待某些事情时被阻塞(最常见,但不是唯一原因)- 代码中的某个地方有一个对外部 Web 服务器的 curl 请求,而超时没有明确设置为某个低且合理的值,例如 10 秒)。一旦所有工作线程都处于等待状态,Apache 就会达到工作线程分叉的限制并停止处理新连接。

这种情况并不特定于将 PHP 作为模块运行的 Apache - 它可能发生在各种堆栈中,例如 nginx+php-fpm。

PS 当 Linux 内核有一个套接字,某个应用程序在 ipv4 和 ipv6 地址系列上监听时,它显示为在 tcp6 上监听。

相关内容