[英]Non-blocking (async) DNS resolving in Java
有没有一种干净的方法可以在 Java 中以非阻塞方式异步解析 DNS 查询(通过主机名获取 IP)(即状态机,而不是 1 个查询 = 1 个线程 - 我想同时运行数万个查询,但是不运行数万个线程)?
到目前为止我发现了什么:
InetAddress.getByName()
实现是阻塞的,看起来标准 Java 库缺少任何非阻塞实现。Future
范式用法,以及非常有限的仅队列实现。Fun
类我错过的任何其他想法/实现?
澄清。 我有相当大(每天几 TB)的日志量。 每个日志行都有一个主机名,它可以来自互联网上的几乎任何地方,我需要该主机名的 IP 地址以进行进一步的统计计算。 行的顺序并不重要,所以,基本上,我的想法是启动 2 个线程:首先遍历行:
第二个线程将:
epoll
/ kqueue
类的技术) Perl 中使用AnyEvent
一个简单模型实现向我表明,我的想法通常是正确的,我可以通过这种方式轻松实现每秒 15-20K 查询的速度(朴素的阻塞实现类似于每秒 2-3 个查询 - 只是为了比较 -所以这就像 4 个数量级的差异)。 现在我需要在 Java 中实现相同的 - 我想跳过推出我自己的 DNS 实现;)
您可能正在寻找基于 MINA的 DNS的Apache 目录服务实现。 JavaDocs 和其他有用的指南位于该页面的左侧边栏中。
在 netty 中有一些关于非阻塞 DNS 的工作,但它仍在进行中,可能只会在 5.0 中发布
我认为,您必须在使用基本套接字支持的原始 UDP 之上或使用 NIO 通道在 TCP 之上自己实现 DNS 客户端协议。
我没有你的问题的答案(我不知道是否有一个 DNS 库可以在你想要的异步模式下运行),而且评论太长了。
但是,您应该能够快速生成一个异步的,而不必自己编写完整的 DNS 处理程序。 警告,我还没有这样做,所以我可能是错的。
从 dnsjava 代码开始,您应该能够实现自己的解析器,该解析器将为您提供发送方和接收方方法。 查看SimpleResolver并查看send
方法。 您应该能够将此方法分解为两种方法,一种是将您的请求发送到调用 TCPClient 或 UDPClient 之前(如您所描述的,此时您将处理在线发送的实际情况,与您的第一个线程),以及一个接收,它将被您的第二个线程调用作为对套接字读取的响应,并处理解析响应。 您可能必须从 SimpleResolver 中复制所有代码(您需要许多私有方法并且许可允许这样做),或者您可以创建自己的版本并在类路径中的 jared 之前简单地加载它,或者,您可以将您的方式反映到相关方法并将它们设置为可访问。
您可以使用netty或mina快速构建网络客户端。 对于文档,我更喜欢 netty。
如果你确实沿着这条路走下去并且可以/想要开源它,如果你遇到麻烦,我可以留出一些时间来帮助你。
Linux 有异步 DNS 查找功能: http : //www.imperialviolet.org/2005/06/01/asynchronous-dns-lookups-with-glibc.html
如果你在 Linux 上,你只需要将它封装在一些 JNI 中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.