有没有解决异步Java中的DNS查询(由主机名获取IP),非阻塞方式(即状态机的清洁方式,而不是1个查询= 1个线程 - 我想同时运行查询几万,但未运行的线程数以万计的)?
我已经发现迄今:
- 标准
InetAddress.getByName()
实现阻止和看起来像标准的Java库缺少任何非阻塞的实现。 - 解决散装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一个简单的模型实现AnyEvent
让我发现,我的想法是正确的一般,我可以很容易地实现速度像15-20K查询每秒这种方式(幼稚阻止执行得就像每秒2-3查询-比较的只是着想-所以这就是像4个数量级的差异)。 现在我需要在Java中实现相同的 - 我想跳过推出我自己的DNS实施;)
它可能是DNS的Apache目录服务实现对MINA的顶部是你在找什么。 的Javadoc和其他有用的指南是在该网页上,在左侧栏。
有在无阻塞DNS一些工作在网状 ,但它仍然在进步,将可能在5.0只发布工作
你会的,我认为,必须使用基本插座的支持来实现自己在原UDP上的DNS客户端协议,或使用NIO渠道TCP之上。
我没有回答你的问题(我不知道是否有将在您需要的异步模式操作DNS库),这是一个评论太长。
但是,你应该能够迅速产生,而无需自己编写完整的DNS处理异步之一。 警告,我没有这样做,所以我可能是完全错误的。
与dnsjava代码,你应该开始能实现自己的解析器,将提供两个发送器和接收器的方法。 退房SimpleResolver ,并期待在send
方法。 你应该能够将此方法分解成两种方法,一种发送运行到呼叫无论是的TcpClient或UDPClient(你会处理的线在这一点上发送实际的,像你描述你的要求,您的第一个线程),以及,一个接收,这将通过你的第二个线程被称为一个套接字读的响应,以及处理解析响应。 您可能不得不复制所有的代码从SimpleResolver(大量的,你需要和私有方法的许可允许的情况下 ),或者,你可以创建自己的版本,只是在你的classpath提前加载的贾里德之一或者,你可以反映自己的方式在问题的方法和设置他们访问 。
你可以迅速地完成构建网络客户端网状或米娜 。 我喜欢网状的文档。
如果你走这条路,可以/想开源,我可以留出一些时间来帮助,如果你陷入困境。
Linux有一个异步DNS查找功能: http://www.imperialviolet.org/2005/06/01/asynchronous-dns-lookups-with-glibc.html
如果你是在Linux上,你只需要来包装了一些JNI。
你有多种选择
选项1:Java 5个的执行者
- 一个固定的线程池:Executors.newFixedThreadPool(INT)
- 未来 :Future表示异步计算的结果。 提供一些方法来检查,如果计算完成,等待它的完成,并获取计算的结果。
选项2:JMS有消息监听
- 需要对JMS提供者等的依赖
选项2:基于演员框架
您可以在这个扩展很好地this.Look 阿卡 。