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