Java 中的非阻塞(异步)DNS 解析

有没有一种干净的方法可以在Java中以非阻塞方式异步解析DNS查询(通过主机名获取IP)(即状态机,而不是1个查询= 1个线程 - 我想同时运行数万个查询,但不运行数万个线程)?

到目前为止,我发现:

  • 标准实现是阻塞的,看起来标准Java库缺少任何非阻塞实现。InetAddress.getByName()
  • 在批量问题中解决DNS讨论了类似的问题,但找到的唯一解决方案是多线程方法(即一个线程在每个给定的时刻只处理1个查询),这并不是真正可扩展的。
  • dnsjava 库也仅阻止。
  • dnsjava有可追溯到2006年的古代非阻塞扩展,因此缺乏任何现代Java并发的东西,例如范式用法,唉,非常有限的仅队列实现。Future
  • dnsjnio项目也是dnsjava的扩展,但它也适用于线程模型(即1查询= 1线程)。
  • asyncorg似乎是我迄今为止针对此问题找到的最佳可用解决方案,但是:
    • 它也是从2007年开始的,看起来被遗弃了
    • 几乎缺少任何文档/javadoc
    • 使用许多非标准技术,如类Fun

我错过了任何其他想法/实现吗?

澄清。我有相当大(每天几TB)的日志量。每个日志行都有一个主机名,几乎可以来自互联网上的任何地方,我需要该主机名的IP地址才能进行进一步的统计计算。行的顺序并不重要,所以,基本上,我的想法是启动2个线程:首先迭代行:

  • 读取一行,解析它,获取主机名
  • 向DNS服务器发送查询以解析给定的主机名,不要阻止答案
  • 将行和 DNS 查询套接字句柄存储在内存中的某个缓冲区中
  • 转到下一行

第二个线程将:

  • 等待DNS服务器回答任何查询(使用/喜欢的技术)epollkqueue
  • 阅读答案,找到它在缓冲区中的哪一行
  • 将具有解析 IP 的行写入输出
  • 继续等待下一个答案

Perl中使用的一个简单的模型实现向我展示了我的想法通常是正确的,我可以很容易地通过这种方式实现每秒15-20K查询的速度(朴素的阻塞实现每秒获得2-3个查询 - 只是为了比较 - 所以这就像4个数量级的差异)。现在我需要在Java中实现相同的功能 - 我想跳过推出我自己的DNS实现;)AnyEvent


答案 1

可能是您在MINA之上实现DNS的Apache Directory Services就是您正在寻找的。JavaDocs 和其他有用的指南位于该页面的左侧栏中。


答案 2

在netty中有一些关于非阻塞DNS的工作,但它仍然在进行中,可能只会在5.0中发布。


推荐