有没有一种干净的方法来异步解析 Java 中的 DNS 查询(通过主机名获取 IP),以非阻塞方式(即状态机,不是 1 个查询 = 1 个线程 - 我想同时运行数万个查询,但是不运行数万个线程)?
到目前为止我发现了什么:
- 标准
InetAddress.getByName()
实现是阻塞的,看起来标准 Java 库缺少任何非阻塞实现。 - Resolving DNS in bulk question 讨论了类似的问题,但找到的唯一解决方案是多线程方法(即一个线程在每个给定时刻仅处理 1 个查询),这不是真正可扩展的。
- dnsjava库也只是阻塞的。
- dnsjava的古老非阻塞扩展可以追溯到 2006 年,因此缺乏任何现代 Java 并发内容,例如
Future
范式使用,以及非常有限的仅队列实现。 - dnsjnio项目也是对 dnsjava 的扩展,但它也适用于线程模型(即 1 个查询 = 1 个线程)。
- asyncorg似乎是迄今为止我找到的针对此问题的最佳可用解决方案,但是:
- 它也是 2007 年的,看起来被遗弃了
- 几乎没有任何文档/javadoc
- 使用了很多非标准的技术,比如
Fun
class
我错过了任何其他想法/实现?
澄清。我有相当大(每天几 TB)的日志量。每个日志行都有一个主机名,该主机名几乎可以来自互联网上的任何地方,我需要该主机名的 IP 地址以进行进一步的统计计算。行的顺序并不重要,所以,基本上,我的想法是启动 2 个线程:首先迭代行:
- 读取一行,解析,获取主机名
- 向 DNS 服务器发送查询以解析给定的主机名,不要阻止回答
- 将线路和 DNS 查询套接字句柄存储在内存中的某个缓冲区中
- 转到下一行
第二个线程将:
- 等待 DNS 服务器回答任何查询(使用
epoll
/kqueue
like 技术) - 阅读答案,找出它在缓冲区中的哪一行
- 将解析 IP 的行写入输出
- 继续等待下一个答案
Perl 中使用的一个简单模型实现AnyEvent
向我表明,我的想法通常是正确的,并且我可以通过这种方式轻松实现每秒 15-20K 查询的速度(天真的阻塞实现每秒查询 2-3 次 - 只是为了比较 - 所以这就像4个数量级的差异)。现在我需要在 Java 中实现相同的功能 - 我想跳过推出我自己的 DNS 实现;)