`

如何解决查找HostName引起JVM挂起,或者响应慢的问题?

阅读更多

由于项目中出现用java的getHostName很慢的问题,而且在多线程中也有问题

 

一种解决方式是不用getHostName,用IP来代替

 

另一种解决方式是在网上搜到的,如下

 

转自:http://tech.watchstor.com/backup-and-archiving-113031.htm

 

  • 摘要:在Java 2 SDK 1.4中,JVM在获得HostName的时候会同时进行IPv4和IPv6查询。如果Domain Name System (DNS) 服务没有配置接受IPv6查询,JVM可能返回Unknown Host异常,如果Domain Name System (DNS) 服务没有正确配置接受IPv6查询,JVM需要等待IPv6查询返回结果,直到超时。这就引起了JVM挂起或响应慢。
  • 标签:虚拟机  JVM  Java

 

环境

产品:WebSphere Application Server

平台:AIX

版本:5.1,6.0

问题

当发现WAS挂起或响应慢的时候,通过 kill -3 产生 javacore 文件,在 javacore 文件中发现大部分的线程堆栈都在执行java.net.InetAddress.getLocalHost,如下:

at java.net.Inet6AddressImpl.getLocalHostName(Native Method)

at java.net.InetAddress.getLocalHost(InetAddress.java:1186)

at org.apache.soap.util.mime.MimeUtils.getUniqueValue(Unknown Source)

at org.apache.soap.rpc.SOAPContext.setRootPart(Unknown Source)

...............................................

解答

在Java 2 SDK 1.4中,JVM在获得HostName的时候会同时进行IPv4和IPv6查询。如果Domain Name System (DNS) 服务没有配置接受IPv6查询,JVM可能返回Unknown Host异常,如果Domain Name System (DNS) 服务没有正确配置接受IPv6查询,JVM需要等待IPv6查询返回结果,直到超时。这就引起了JVM挂起或响应慢。

这个问题有以下解决方案:

1.Java解决方案

如果是一般的Java应用程序,可以在启动JVM的时候加入

-Djava.net.preferIPv4Stack=true

参数。

如果是WebSphere Application server,执行如下步骤:

a.登录管理控制台,打开“服务器 > 应用服务器 > 服务名称 > 进程定义 > JVM虚拟机 > 定制属性” 页面。

b.在页面中添加如下定制属性

名称: java.net.preferIPv4Stack

值: true

c.点击“确定”,并保存配置。

d.重新启动应用服务器

2.AIX解决方案

a.安装以下APAR:

AIX V520: IY47908

AIX V510: IY48783

要确认这个补丁是否已经安装,可以用如下命令:

instfix -ik IY#####

b.在确认以上APAR已经安装后,编辑/etc/netsvc.conf文件,在其中加入:

hosts=bind4,local

或者在启动WebSphere Application Server前,设置系统环境变量:

export NSORDER=bind4,local

3.Domain Name System(DNS)解决方案

配置DNS服务器忽略IPv6查询请求

4.Network Information Service (NIS) 解决方案

如果系统使用NIS来解析Hostname,可以通过修改/etc/hosts和/etc/netsvc.conf文件来移除NIS。

具体请参考以下文档:http://www-1.ibm.com/support/docview.wss?uid=swg21170467

 

 

另注意:

 

现在才知道是IP地址的问题,在FC4中默认的是IPv6 socket,JDK1.4支持的应该是IPv4,具体原因可以查看SUN公司给出的解释.
解决办法是在运行JAVA程序时加上 -Djava.net.preferIPv4Stack=true 如:

java -Djava.net.preferIPv4Stack=true application.

详悉信息请查看下面的连接,如果那位朋友有更好的解决办法盼告知.

http://java.sun.com/j2se/1.4.2/docs/...roperties.html

发现禁用IPV6,是比较好的解决方法.

--------------------------------------------------------------------------------


修改 /etc/modprobe.conf 文件,增加

alias net-pf-10 off
alias ipv6 off

这样就不用增加参数 "-Djava.net.preferIPv4Stack=true ",重起即可.

 

---------------------------------------------

补充:

在 Java 应用中JVM 也会缓存DNS 的解析结果,这个缓存是在InetAddress 类中完成
的,而且这个缓存时间还比较特殊,它有两种缓存策略:一种是正确解析结果缓存,另一
种是失败的解析结果缓存。这两个缓存时间由两个配置项控制,配置项是在%JAVA_
HOME%\lib\security\java.security 文件中配置的。两个配置项分别是networkaddress.cache. ttl
和networkaddress.cache.negative.ttl,它们的默认值分别是-1(永不失效)和10(缓存10 秒)。
要修改这两个值同样有几种方式,分别是:直接修改java.security 文件中的默认值、
在Java 的启动参数中增加-Dsun.net.inetaddr.ttl=xxx 来修改默认值、通过InetAddress 类动
态修改。
在这里还要特别强调一下,如果我们需要用InetAddress 类解析域名时,一定要是单
例模式,不然会有严重的性能问题,如果每次都创建InetAddress 实例,每次都要进行一
次完整的域名解析,非常耗时,这点要特别注意。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics