我有一个托管多个 json API 的 Apache 服务器。
该服务器运行带有 Apache 和 Mysql 的 Ubuntu 16.04.4 LTS。
除一个 API 外,所有 API 的响应时间都非常好!从特定 API 获取 json 响应大约需要 5 秒,而其他 API 则需要几毫秒。
我检查了多件事,但没有成功:
1)SQL 查询几乎立即运行(有或没有缓存 - 我都试过了)
2)我们的开发人员添加了一个自定义标头,以了解 API 生成 json 响应所需的时间:2-3 毫秒
3) 使用 wget 从远程计算机或本地服务器调用 API 会得到相同的结果:需要 5 秒才能获得回复。根据浏览器开发模式,这 5 秒用于“等待”。Google Chrome 显示“等待第一个字节”。然后根据开发模式,数据传输似乎很快(几毫秒)
4)Apache 似乎不会被 https 请求淹没,请参见显示服务器状态页面的屏幕截图 服务器状态
5)通过多个防火墙访问 https API,但没有反向代理
作为调试过程的一部分,我尝试提高服务器性能:
我将虚拟机移到了最不繁忙的 VMware 主机上
我将此虚拟机移至基于 SSD 的数据存储
你知道为什么 Apache 回复这么慢吗?你知道解决这个问题的方法吗?
感谢您的帮助
托马斯
答案1
几天前我发现了以下帖子:Apache 在响应之前有很长的延迟 这个问题看起来和我的问题类似,但听起来与 IPv6 有关。由于我的服务器上已禁用 IPv6,我认为该解决方案不适合解决我的问题。
为了最后一次尝试解决这个问题,我还是尝试了所描述的解决方案:我只是在 /etc/resolv.conf 中添加了“options single-request-reopen”,然后 5 秒的延迟就消失了。
目前,我不太明白为什么这个设置能解决我的性能问题,因为我的服务器上禁用了 IPv6。
此外,Apache 中主机名查找已被禁用。
经过仔细的调查……
1) 这个新的 Json API 使用 Google Firebase 进行身份验证,这意味着需要 DNS 解析才能访问 Google 服务。我在之前的调查中忘记了这一点……我以为 DNS 不会成为问题。我错了。
2)仅 IPv4 服务器上的 IPv6 查询
基本上,Linux 服务器依赖 getaddrinfo 进行 dns 解析。根据手册页(gai.conf 是 getaddrinfo 配置文件):
“对 getaddrinfo(3) 的调用可能会返回多个答案。根据 RFC 3484,必须对这些答案进行排序,以便成功率最高的答案位于列表的首位。RFC 提供了一种排序算法。”
根据 RFC 3484:
“默认策略表的另一个作用是优先使用 IPv6 地址进行通信,而不是使用 IPv4 地址进行通信,”
回到“单一请求重新打开”:
“解析器对 A 和 AAAA 请求使用相同的套接字。某些硬件会错误地只发回一个回复。发生这种情况时,客户端系统将等待第二个回复。启用此选项可以改变此行为,这样如果来自同一端口的两个请求未得到正确处理,它将关闭套接字并在发送第二个请求之前打开一个新套接字。”
我认为我的服务器正在等待第二次回复......这花了 5 秒。“single-request-reopen”让我绕过了这个问题。
3)优先处理 IPv4 DNS 查询:
我也改变了 getaddinfo 行为以确保 IPv4 通信是首选,请参阅 /etc/gai.conf
# For sites which prefer IPv4 connections change the last line to
#
precedence ::ffff:0:0/96 100
托马斯