Python gethostbyaddr 速度很慢

Python gethostbyaddr 速度很慢

我今天遇到了一个无法解释的问题,希望有人能给我指明正确的方向。

我有一组运行 Python 脚本的 EC2 服务器。当用户连接到我的服务器(通过负载均衡器处理)时,我会根据他们的 IP 地址(或 PTR)获取他们的反向名称。

到目前为止,这是我使用的代码:

import socket

details = socket.gethostbyaddr(request.user_ip)
print('User PTR is', details[0])

我今天意识到查询gethostbyaddr可能需要几秒钟(有些查询甚至需要 300 秒!!)。平均时间为 1 秒,常见时间为 20 到 30 秒之间!

(有人提到gethostbyaddr5 秒后超时,但就我的情况而言似乎并非如此)。

现在,阅读有关的内容gethostbyaddr,似乎它使用resolv.conf(我正在使用 Debian 12)来查找反向。在我的服务器中,该文件的内容是:

nameserver 172.31.0.2
search .

所以我的服务器依赖于 AWS 的 VPC DNS 解析器。

我所做的是跟踪命令之间的时间gethostbyaddr,如果它超过 1 秒,则显示持续时间以及 IP。

当我有一些 IP 时,我会在同一个服务器上但在另一个 Python shell 上运行相同的代码,并且通常会在几毫秒内得到结果,或者出现错误(未解析的主机),一般来说很快。少数错误可能需要几秒钟(甚至几分钟)才能显示出来。

我的假设是 Python 正在排队gethostbyaddr命令以按顺序运行它们,尽管具有多个进程,并且如果其中一些进程卡住,则其他进程将被延迟,直到某些套接字被释放以用于该查询。

这有意义吗?这可能吗?

所以我尝试了一种替代方法:相反,我使用 arpa DNS(“[ip-in-reverse].in-addr.arpa。”)构建反向查询,然后直接使用 Cloudflare 的 DNS(1.1.1.1)自行查询 DNS。

这样做会使持续时间减少到几毫秒,从而解决问题。

我“有点”修复了该错误,但无法准确解释它发生的原因。我有相当多的服务器使用无效反向连接到我的 EC2 实例,因此卡住是gethostbyaddr有道理的,但使用相同代码的其他进程是否可能卡在某个队列中?也许在 Linux 级别?

以下是我的假设:

  1. Debian(Linux)正在对查询进行排队以检索 gethostbyaddr,当一定数量的查询花费的时间太长时,其他查询将放入队列中然后再进行处理
  2. 亚马逊的 DNS 出现了一些问题,或者对查询实施了一些速率限制或延迟,导致解析时间更长
  3. ???

我遗漏了什么可以解释延迟的原因?

这里不需要代码示例,因为问题与代码没有直接关系,而是与如何gethostbyaddr使用有关。

感谢您的帮助。

答案1

您获得答案的速度取决于负责域的 DNS 服务器回答查询的速度。除非查询和结果已被缓存,否则 AWS DNS 服务器只会将查询转发到适当的服务器(也可能转发到另一个服务器)。由于 DNS 传统上是用 UDP 完成的,因此外部服务器可能根本不响应,在这种情况下,请求将重试,直到发生超时。

一般来说,当查询需要外部解析时,在代码中包含阻塞 DNS 查询(如 gethostbyaddr)不是一个好主意。您完全依赖某个外部服务器来继续执行程序,但无法控制查询需要多长时间。

相关内容