繁体   English   中英

Python异步反向DNS查找

[英]Python Asynchronous Reverse DNS Lookups

我希望在很短的时间内进行大量的反向DNS查找。 我目前使用socket.gethostbyaddr和concurrent.futures线程池实现了异步查找,但仍然没有看到所需的性能。 例如,脚本大约需要22分钟才能完成2500个IP地址。

我想知道是否有更快的方法来做到这一点,而不采取像adns-python这样的东西。 我发现这个http://blog.schmichael.com/2007/09/18/a-lesson-on-python-dns-and-threads/提供了一些额外的背景知识。

代码片段:

ips = [...]
with concurrent.futures.ThreadPoolExecutor(max_workers = 16) as pool:
    list(pool.map(get_hostname_from_ip, ips))
def get_hostname_from_ip(ip):
    try:
        return socket.gethostbyaddr(ip)[0]
    except:
        return ""

我认为部分问题是许多IP地址没有解决和超时。 我试过了:

socket.setdefaulttimeout(2.0)

但似乎没有效果。

我发现我的主要问题是IP无法解决,因此套接字不遵守设置超时并在30秒后失败。 请参阅Python 2.6 urlib2超时问题

由于缺乏对IPv6的支持(没有补丁), adns-python是不行的。

搜索后我发现: 使用dnspython反向DNS查找并在我的代码中实现了类似的版本(他的代码也使用可选的线程池并实现超时)。

最后,我使用带有concurrent.futures线程池的dnspython进行异步反向DNS查找(请参阅Python:共享主机中的反向DNS查找Dnspython:设置查询超时/生命周期 )。 超时为1秒时,2500个IP地址的运行时间从大约22分钟减少到大约16秒。 差异很大可能归因于套接字上的Global Interpreter Lock和30秒超时。

代码片段:

import concurrent.futures
from dns import resolver, reversename
dns_resolver = resolver.Resolver()
dns_resolver.timeout = 1
dns_resolver.lifetime = 1
ips = [...]
results = []

with concurrent.futures.ThreadPoolExecutor(max_workers = 16) as pool:
    results = list(pool.map(get_hostname_from_ip, ips))

def get_hostname_from_ip(ip):
    try:
        reverse_name = reversename.from_address(ip)
        return dns_resolver.query(reverse_name, "PTR")[0].to_text()[:-1]
    except:
        return ""

请使用异步DNS ,其他一切都会给你带来很差的性能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM