氟塑料离心泵www.buybeng.com

jquery教程http://www.software8.co/wzjs/jquery/

Java建立Socket慢的问题

Java编程中,一般都是使用下面的语句来建立Socket

String ip ="192.168.0.100";

int port = 8090;

Socket socket = new Socket(ip,port);

//.......

 

在有些JDK和JRE的版本中,会发生这个new Socket语句非常缓慢的问题(Linux和windows环境中都可能有这种问题)。

 

我遇到这种问题,还是在Java中使用Tomcat,配置了一个数据库连接池,最小连接数配了10个,在软件一启动时,就会建立这些连接,结果就发现启动过程卡在这里了,悲剧了。。。。

更有甚者,在某个Java做得项目中,启动时,会建立一个长连接的连接池,一启动时就会建立一些Socket客户端,在启动后并发访问中来使用,结果,等啊等啊。。。

 

(最讨厌的是,不知道到底哪些版本出这样的问题,好像JDK1.5时看到过这个问题,后面的版本也有时候有问题,再有就是IBM的JDK也说不定哪个版本会出这个问题,而且,Linux平台出现问题的时候更多)

 

经过这两次,我下决心找一下这个问题,后来发现网上也有人讨论这个问题,但是很少,后来在sun(当时Java还是sun的)的bug库中有个条目在描述这个问题,链接找不到了,大体上的描述就是:

 

Java中,使用字符串的主机和整数的端口号来构造Socket的构造函数是

 

public Socket(String host, int port) throws UnknownHostExceptionIOException

 

可以明确的是,第一个参数的含义是host,因此,java将第一个参数字符串会理解成主机名,因此,在建立Socket时会根据主机名来查找主机的IP地址。因此,即便实际给的参数是一个字符串中包含的IP地址,但是,这是Java所无法分辨的。

 

因为机器的DNS配置不大对头,到DNS查找主机对应IP,消耗了太多的时间,所以,建立连接变得非常缓慢,就造成了前边所描述的问题。至于怎样到DNS查找,就不是本文所描述的内容了。

 

如果想通过编程避免这个问题,应该怎么处理呢?我们可以看到,Socket还可以这样建立

public Socket(InetAddress address, int port) throws IOException

 

而InetAddress可以通过如下的方法来创建:

 

public static InetAddress getByName(String host) throws UnknownHostException

 

public static InetAddress getByAddress(byte[] addr) throws UnknownHostException

 

使用字符串的host来创建InetAddress,可以想象,和使用字符串的host来创建Socket一样会缓慢(因为需要

到DNS),而是要字节数组来创建又是如何呢?我们看这个函数的解释:

在给定原始 IP 地址的情况下,返回 InetAddress 对象。参数按网络字节顺序:地址的高位字节位于getAddress()[0] 中。

此方法不会阻塞,即不执行任何反向名称服务查找操作。

IPv4 地址 byte 数组的长度必须为 4 个字节,IPv6 byte 数组的长度必须为 16 个字节

 

首先可以明确看到,不执行反向名称服务查找查找;第二,讲IP地址转换成字节数组。因为Java看到这个函数时已经知道送来的是IP地址,所以没有查DNS的问题了。

 

从这里可以看到,其实这个问题是因为我们在送参数时,没有更加准确的去区分IP地址和主机名这两个概念。送IP地址和送主机名的场景如果清晰的区分开来就不会出这种问题了。

 

一个很糟糕的是Java的JDBC,我记得好像JDBC是建立的Socket上的,而且是字符串方式送的主机或IP地址,所以,这个问题会影响到使用数据库的Java应用,如前边提到的。

再有,如果打算使用字符串这种构造地址或Socket的方式,应该配置DNS,使之能够很快的找到主机。说白了,在windows下,你可以在windows\system32\drivers\etc\hosts文件这,加入一行(示例如下):

192.168.0.100 192.168.0.100

这样就告诉系统,在寻找主机名“192.168.0.100”时,从这里就返回IP地址是192.168.0.200。这样就省了很多的时间。对于Linux,是/etc/hosts文件。

结论:

(1)如果是自己建立TCP连接这类的应用,在可能的话,使用getByName这种方式,直接传IP地址;

(2)修改hosts文件,有些时候能够修改,有些情况,可能没有办法改别人系统的文件;

(3)配置好的DNS

posted on 2013-03-29 11:56 你爸是李刚 阅读(1602) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航:
 
<2013年3月>
242526272812
3456789
10111213141516
17181920212223
24252627282930
31123456

导航

统计

常用链接

留言簿

随笔档案

文章档案

技术网站

行业网站

搜索

最新评论

阅读排行榜

评论排行榜

站长网 氟塑料离心泵 注塑机 液晶广告机