我正在向 Apache 服务器上运行的简单 PHP API 推送中等流量(大约 20 个请求/秒)。Apache 服务器处于休眠状态(mod_status 几乎未记录一个活动请求),但是尽管如此,我还是看到“连接被拒绝”错误定期发生。我尝试结束uname -n
和MinSpareServers
,但毫无效果。
我在负载下运行了这样的诊断脚本,发现大约十分之一的请求会失败,并显示“连接被拒绝”
while [ 1 ]; do echo "" | telnet <server> 80; sleep 1; done
但是,在本地机器上运行类似请求时,一切正常。
while [ 1 ]; do echo "" | telnet localhost 80; sleep 1; done
最初我以为可能是所有请求都来自同一个客户端,而服务器被限制了。然而,在负载下,尝试连接的所有其他主机都会遇到相同的间歇性问题。
localhost 行为不同的事实表明这是一个网络问题,而不是 apache 问题,但我不确定在哪里诊断这个问题。是否有日志记录可以让我检查/启用以查看连接拒绝是否发生在操作系统(或可能是 iptables)级别。
相关软件:
- Ubuntu Lucid,2.6.33 内核
- Apache 2.2.14
更新:
在我们的 iptables 配置中,我可以在“Chain TCPACCEPT”下看到以下规则:
655K 34M ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp flags:0x17/0x02 limit: avg 12/sec burst 24
看来这个速率限制肯定会导致一些“连接被拒绝”错误。我可以暂时禁用防火墙,看看这是否能解决问题,但我认为这条规则是为了帮助应对 DOS 攻击。当前的限制对于平均值和突发来说似乎都太小了。什么是更合理的限制(我可以在我们的 iptables 配置中调整这些限制)?
答案1
如果这种情况定期发生,则很可能不是 iptables,但要查看 iptables 规则,请运行
sudo iptables -L -n -v
您的 iptables 日志将位于 /var/log 下,但根据您的配置可能会有所不同。检查 /etc/rsyslog.d 目录下是否有您的 iptables 日志位置的配置文件。
您还可以使用 netstat 或 lsof 来查看端口上发生的情况。
netstat -an | grep "80.*LIST"
lsof -i :80
最后,您可能需要进行网络捕获以查看是否有 TCP RST 被发送回来或者根本没有响应回来 - 为此使用 tcpdump。
问题更新更新:
如果禁用该 iptables 规则会发生什么?它会执行几项操作,但其中一项操作似乎是限制仅将 syn 数据包设置为平均每秒 12 个且具有突发限制的 tcp 段。如果您发送的平均速度为每秒 20 个,我相信您超出了 iptables 规则中设置的限制。
因此,您可以关闭防火墙上的此规则进行测试(我不建议完全关闭防火墙),或者您可以将其修改为 22/秒,突发为 36。
在修改之前,我会认真考虑修改那些您不熟悉或者不确定其存在原因的配置。