我们的托管 PHP Web 应用程序的服务器频繁出现停机
服务器信息 [Nginx,FreeBSD] Web 应用程序 [PHP 5.6,MYsql 5.7]
我已经查看了 Nginx 日志,以下是我的发现
error.log 有一些以下日志
2023/05/31 19:48:16 [error] 1456#100101: *7408 open() "/usr/local/www/html/uploads/files/22816683587.pdf" failed (2: No such file or directory), client: 5.255.231.177, server: localhost, request: "GET /uploads/files/22816683587.pdf HTTP/1.1", host: "somesite.com"
有没有像这样的几个请求从不同的 IP 地址访问来自服务器的随机 pdf 文件
debug.log 有一些溢出日志
May 31 18:43:40 ip-XX-XX-XX-XX kernel: sonewconn: pcb 0xfffff800e1910dc8: Listen queue overflow: 193 already in queue awaiting acceptance (265 occurrences)
May 31 18:44:40 ip-XX-XX-XX-XX kernel: sonewconn: pcb 0xfffff800e1910dc8: Listen queue overflow: 193 already in queue awaiting acceptance (330 occurrences)
May 31 18:45:40 ip-XX-XX-XX-XX kernel: sonewconn: pcb 0xfffff800e1910dc8: Listen queue overflow: 193 already in queue awaiting acceptance (314 occurrences)
当我在停机时检查以下 netstat 结果时
root@myIP:~ # netstat -Lan
Current listen queue sizes (qlen/incqlen/maxqlen)
Proto Listen Local Address
tcp6 0/0/128 *.443
tcp4 0/0/128 *.80
tcp4 0/0/128 *.443
tcp4 0/0/10 127.0.0.1.25
tcp4 0/0/128 *.22
tcp6 0/0/128 *.22
tcp46 0/0/80 *.3306
tcp4 193/0/128 127.0.0.1.9000
unix 0/0/80 /tmp/mysql.sock
unix 0/0/4 /var/run/devd.pipe
unix 0/0/4 /var/run/devd.seqpacket.pipe
从上面我发现“tcp4 193/0/128 127.0.0.1.9000”它由 PHP FPM 服务使用
我也检查了 Php-FPM 日志,没有记录耗时超过 5 秒的缓慢进程,有一些,但这些记录是在服务器变慢或关闭时记录的
Nginx.conf 中设置了一些 Nginx 和 FastCGi 参数
client_header_timeout 3000;
client_body_timeout 3000;
fastcgi_read_timeout 3000;
client_max_body_size 32m;
fastcgi_buffers 8 128k;
fastcgi_buffer_size 128k;
server_name_in_redirect off;
server_names_hash_bucket_size 64;
server_names_hash_max_size 8192;
我们启用了 MySQL 的慢查询日志,但是没有任何内容记录到其中,结果是空的。
由于服务器正在使用 AWS 实例,我们联系了 AWS,他们告诉我们,有时会随机出现 CPU 使用率高的情况,但数据库没有问题,看起来很健康
我们询问他们我们是否遭受了 DDO 攻击,但他们拒绝回答,并称网络统计数据没有显示这一点。
我们正在努力了解并找到此次服务器停机的确切原因或过程。
请帮忙,提前致谢
更新
内核:sonewconn:pcb 0xfffff80007326c40:监听队列溢出:1537 已在队列中等待接受(发生 167 次)
我增加了监听队列的限制,但现在它也超载了
答案1
在我看来,你的思路是对的。如果你仔细看看下面的输出netstat -Lan
:
root@myIP:~ # netstat -Lan
Current listen queue sizes (qlen/incqlen/maxqlen)
Proto Listen Local Address
tcp4 193/0/128 127.0.0.1.9000
它告诉你队列的长度(qlen)是193而最大长度仅为128(maxqlen)。由于队列长度超过了最大长度 128,因此您正在丢弃连接。以下日志消息也证实了这一点
May 31 18:45:40 ip-XX-XX-XX-XX kernel: sonewconn: pcb 0xfffff800e1910dc8: Listen queue overflow: 193 already in queue awaiting acceptance (314 occurrences)
其中也提到了数字193。
您可以确认您的最大查询长度设置为 128:
sysctl kern.ipc.somaxconn
您可能希望将其设置为更高的值,如下所示:
sysctl -w kern.ipc.somaxconn=1024
为了使此更改持久,以便它在重新启动后仍然存在,您需要在文件中添加一行/etc/sysctl.conf
:
kern.ipc.somaxconn=1024
这个更大的队列可能会让你的侦听队列溢出消息消失并避免连接断开/停机。
但是,应该调查为什么会有这么多请求,这是否是预期负载,或者是否存在一些自动/脚本攻击。在后一种情况下,配置fail2ban
黑名单 IP 地址会是一个很好的缓解措施,这些 IP 地址每分钟下载的 PDF 文件数量达到给定阈值或类似情况。