上次问了个nio低级问题: http://topic.csdn.net/u/20120119/11/c5a93b76-c1c8-48a6-be09-91f118f40e68.html ,了解了nio避免了开线程所带来的操作系统开销和线程切换的开销,性能可以提升很大。那么这次我在用nio的时候碰到了一些问题,特此来问问大家:我现在在使用nio中碰到这么个问题:网络通讯中除了域名解析外,其他的都已经使用了nio模型,唯独域名解析找不到nio中对应的方法:我这里现在需要做一个类似代理服务器之类的程序,大量客户端连上来请求连接远程主机,其中绝大部分都是通过域名进行连接的。而SocketChannel.connect需要传入的是SocketAddress。
但构造带目标地址的SocketAddress只有3个方法:1、通过InetSocketAddress的构造函数传入InetAddress(附带port)构造;2、通过InetSocketAddress的构造函数传入目标地址的String(附带port)构造;3、通过InetSocketAddress.createUnresolved传入目标地址的String(附带port)构造。
如果使用第1种方法,那么需要首先构造一个InetAddress。在只知道域名但不知道IP地址的情况下,构造方法只有2个:1、InetAddress.getByName;2、InetAddress.getAllByName。而这两个方法都是非nio的(阻塞的),每次解析新的域名(曾经解析过的域名有缓存,会立即解析完毕)需要阻塞零点几秒。此路不通。
如果使用第2个方法,经过试验,在new InetSocketAddress的时候,如果传入的是没有解析过的域名会阻塞零点几秒。此路也不通。
如果使用第3个方法,InetSocketAddress.createUnresolved确实会立即返回没有阻塞,但得到的InetAddress组成的SocketAddress传入到SocketChannel.connect后,会立即throw UnresolvedAddressException。此路还是不通。如果不使用nio而使用多线程模型(比如开一个线程池进行域名解析),又回到了老的多线程模型上去了,使用nio的优势没有了。如果使用线程池进行域名解析,经过测试,在没有域名解析的情况下服务器大约可以同时服务10000个用户,但有域名解析后,服务器最多只能同时服务于2000个用户了,性能降低很多。有谁知道这个问题该怎么解决吗?

解决方案 »

  1.   

    如果没有解决方案的话,是不是说明Java不支持异步解析域名?是不是一个功能缺陷?
      

  2.   

    都没找到解决方案,打算自己实现一个nio的InetAddress,有谁有兴趣么?
      

  3.   

    大家在用nio实现代理服务器的时候,域名解析通常是怎么做的?都用的是多线程/线程池吗?有没有碰到过这个问题呢?
      

  4.   

    我正在实现nio的域名解析,大家有什么好的建议吗?有没有什么好的实现方法?
      

  5.   

    如果用多线程/线程池实现nio的域名解析,又回到老路上去了,也和初衷相背离。
    但除了用多线程/线程池实现nio的域名解析不知道还有其他方法吗?
      

  6.   

    第一次访问缓存下被 我肤浅了..其实并不是强调用了NIO就不用多线程 两者各有优势 说实话 大量客户端 并且请求时间较短 我个人建议你用多线程 不用NIO
      

  7.   

    确实,并不是强调用了NIO就不用多线程,所以一开始才用了多线程/线程池去解析域名的。但发现服务器端有可能需要有大量域名需要解析,消耗比网络数据传输本身的的消耗还要大,导致了能负载的用户数急剧下降(从10000到2000),所以才去寻找异步解析域名的方案。原先能负载10000个用户也并不是完全的单线程,而是开了固定数量的少量线程(而不是根据用户数的增加而增加)。而现在即使在线程池中开了大量线程,如果域名解析请求数量一多,还是有很大可能占满整个线程池,导致后续域名解析进行排队。而这个线程池中的线程树受到系统的限制,也无法再开多了(再开多的话,经过测试,系统会不稳定,系统本身的响应变慢)。现在就碰到这么个情况,求解决。
      

  8.   

    是不是可以给Oracle提个BUG,建议在nio中加入域名解析?
      

  9.   

    有谁知道Java中怎么获取系统中配置的DNS服务器吗?要求跨平台的,不仅仅是windows/linux/mac/android,可能还有其他Java平台。现在实现nio域名解析中碰到了这个问题。
      

  10.   


    你在哪个公司做DNS服务方面的开发?...
      

  11.   

    可能不能称为是公司吧,是一个基金会,有这样的开发需求。一直找不到nio域名解析的方法,烦啊。
      

  12.   

    ..抱歉我刚从一个做DNS服务方面的公司离职  如果我还在的话或许会替你问问高手的..
    不过我还是没太明白你现在的问题在哪里
    Java的Socket(准确的说是InetAddress)一般都会在访问域名后缓存域名对应的IP地址 
      

  13.   

    最近也在搞socket,学习下。。
      我用的不是nio,如果这个好用的话,我想我也要改改代码了