上次问了个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个用户了,性能降低很多。有谁知道这个问题该怎么解决吗?
但构造带目标地址的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个用户了,性能降低很多。有谁知道这个问题该怎么解决吗?
但除了用多线程/线程池实现nio的域名解析不知道还有其他方法吗?
你在哪个公司做DNS服务方面的开发?...
不过我还是没太明白你现在的问题在哪里
Java的Socket(准确的说是InetAddress)一般都会在访问域名后缓存域名对应的IP地址
我用的不是nio,如果这个好用的话,我想我也要改改代码了