是否有一种干净的方法以非阻塞的方式异步解析Java中的DNS查询(通过主机名获取IP)(即状态机,而不是1个查询= 1个线程 - 我想运行数万个查询同时,但没有运行数万个线程)?
到目前为止我发现了什么:
InetAddress.getByName()
实现阻塞,看起来标准Java库缺少任何非阻塞实现。Future
范例使用,唉,只有非常有限的队列实现。Fun
class 我错过了其他任何想法/实施?
澄清即可。我有一个相当大(每天几TB)的日志量。每个日志行都有一个主机名,可以来自互联网上的任何地方,我需要一个IP地址作为我的进一步统计计算的主机名。行的顺序并不重要,因此,基本上,我的想法是启动2个线程:首先迭代线:
第二个线程将:
epoll
/ kqueue
类似技术) Perl中使用AnyEvent
的简单模型实现向我展示了我的想法通常是正确的,我可以通过这种方式轻松实现每秒15-20K查询的速度(天真的阻塞实现每秒2-3次查询 - 只是为了比较 - 这就像4个数量级的差异)。现在我需要在Java中实现相同的功能 - 我想跳过我自己的DNS实现;)
答案 0 :(得分:5)
可能是MINA顶部的Apache Directory Services implementation of DNS正是您所寻找的。 JavaDocs和其他有用的指南都在该页面的左侧边栏中。
答案 1 :(得分:5)
in netty中有一些关于非阻止DNS的工作,但它仍在进行中,可能只会在5.0中发布
答案 2 :(得分:3)
我认为,您必须使用基本套接字支持在原始UDP之上自己实现DNS客户端协议,或者使用NIO通道在TCP之上实现DNS客户端协议。
答案 3 :(得分:2)
我对你的问题没有答案(我不知道是否有一个可以在你想要的异步模式下运行的DNS库)这对评论来说太长了。
但是,您应该能够快速生成异步,而无需自己编写完整的DNS处理程序。警告,我没有这样做,所以我可能都错了。
从dnsjava代码开始,您应该能够实现自己的解析器,它将为您提供发送方和接收方方法。查看SimpleResolver并查看send
方法。您应该能够将此方法分解为两种方法,一种方法是将您的请求运行到TCPClient或UDPClient的调用(此时您将处理实际的线路发送,如您所述,你的第一个线程)和一个接收,它将被你的第二个线程调用作为对套接字读取的响应,并处理解析响应。您可能必须复制SimpleResolver中的所有代码(许多您需要的私有方法和licensing allows for it),或者,您可以创建自己的版本,只需将其加载到您的jared之前。 classpath,或者,您可以反映您对相关方法的看法set them accessible。
您可以使用netty或mina快速构建网络客户端。我更喜欢netty用于文档。
如果你沿着这条路走下去并且想要开源,我可以留出一些时间来帮助你解决问题。
答案 4 :(得分:1)
Linux具有异步DNS查找功能:http://www.imperialviolet.org/2005/06/01/asynchronous-dns-lookups-with-glibc.html
如果您使用的是Linux,那么 需要将其包含在某些JNI中。
答案 5 :(得分:0)