Java 中的非阻塞(异步)DNS 解析
2022-09-01 12:16:19
有没有一种干净的方法可以在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服务器回答任何查询(使用/喜欢的技术)
epoll
kqueue
- 阅读答案,找到它在缓冲区中的哪一行
- 将具有解析 IP 的行写入输出
- 继续等待下一个答案
Perl中使用的一个简单的模型实现向我展示了我的想法通常是正确的,我可以很容易地通过这种方式实现每秒15-20K查询的速度(朴素的阻塞实现每秒获得2-3个查询 - 只是为了比较 - 所以这就像4个数量级的差异)。现在我需要在Java中实现相同的功能 - 我想跳过推出我自己的DNS实现;)AnyEvent