概述
客户环境为was中间件、db2,java应用,在最近一段时间发现登录异常缓慢,详细内容见下文描述。
故障现象
客户端应用访问非常慢,多达12秒或者更长时间,由was中间件使用连接池访问后端的db2数据库。
分析详情
可以从分割为2断请求过程,第一段是从客户端到was中间件,第二段是was中间件到db2数据库。正常来说,第一段只要访问正常就可以快速把请求发送到was
应用服务器,这一段网络没有更改可以忽略,第二段was的连接池使用是重点需要排查部分,经现场人员“测试连接”,发现最简单的查询语句也要超过12秒才能返回:

2.
抓取tcp包分析
“测试连接”返回时间长,有一种可能就是网络延时很高,通过tcpdump抓取流量包,经分析并没有发现延时问题,说明在收到tcp连接之前耗时太长。
|
借助wsadmin工具产生线程堆栈 wsadmin>set
jvm [$AdminControl completeObjectName type=JVM,process=server1,*] wsadmin>$AdminControl invoke $jvm
dumpThreads |
在测试连接过程中连续多次产生堆栈进行排查
连接线程长时间停留在下面堆栈中:
|
3XMTHREADINFO "WebContainer : xxx"
(TID:0x000000002548C300, sys_thread_t:0x000000000B3F70F8, state:R, native
ID:0x00000000000000D4) prio=5 4XESTACKTRACE at
java/net/Inet6AddressImpl.getHostByAddr(Native Method) 4XESTACKTRACE at
java/net/InetAddress$1.getHostByAddr(InetAddress.java:877(Compiled Code)) 4XESTACKTRACE at
java/net/InetAddress.getHostFromNameService(InetAddress.java:555(Compiled
Code)) 4XESTACKTRACE at
java/net/InetAddress.getHostName(InetAddress.java:498(Compiled Code)) 4XESTACKTRACE at
java/net/InetAddress.getHostName(InetAddress.java:470(Compiled Code)) 4XESTACKTRACE at
java/net/InetSocketAddress.getHostName(InetSocketAddress.java:224(Compiled
Code)) 4XESTACKTRACE at
java/net/SocksSocketImpl.connect(SocksSocketImpl.java:355(Compiled Code)) 4XESTACKTRACE at
java/net/Socket.connect(Socket.java:536(Compiled Code)) 4XESTACKTRACE at
com/ibm/db2/jcc/t4/x.run(x.java:34(Compiled Code)) 4XESTACKTRACE at
java/security/AccessController.doPrivileged(AccessController.java:241(Compiled
Code)) 4XESTACKTRACE at
com/ibm/db2/jcc/t4/wb.a(wb.java:394(Compiled Code)) 4XESTACKTRACE at
com/ibm/db2/jcc/t4/wb.<init>(wb.java:90(Compiled Code)) 4XESTACKTRACE at com/ibm/db2/jcc/t4/a.y(a.java:320(Compiled
Code)) 4XESTACKTRACE at
com/ibm/db2/jcc/t4/b.a(b.java:1769(Compiled Code)) 4XESTACKTRACE at
com/ibm/db2/jcc/am/jb.a(jb.java:608(Compiled Code)) 4XESTACKTRACE at com/ibm/db2/jcc/am/jb.<init>(jb.java:560(Compiled
Code)) 4XESTACKTRACE at
com/ibm/db2/jcc/t4/b.<init>(b.java:316(Compiled Code)) 4XESTACKTRACE at
com/ibm/db2/jcc/DB2PooledConnection.<init>(DB2PooledConnection.java:84) 4XESTACKTRACE at com/ibm/db2/jcc/DB2ConnectionPoolDataSource.getPooledConnectionX(DB2ConnectionPoolDataSource.java:411) 4XESTACKTRACE at
com/ibm/db2/jcc/DB2ConnectionPoolDataSource.getPooledConnection(DB2ConnectionPoolDataSource.java:220) 4XESTACKTRACE at com/ibm/ws/rsadapter/DSConfigurationHelper$1.run(DSConfigurationHelper.java:1292) |
确认与下面函数有关
java/net/Inet6AddressImpl.getHostByAddr(Native
Method)
默认情况下,JVM将尝试对getHostByAddr()获取主机名方法使用操作系统级DNS解析器。当操作系统没有及时响应getHostByAddr()方法时就出现了长时间的等待,根本原因可能会有所不同,可能是DNS服务器配置问题、操作系统问题、防火墙等。
如下:
A. 修改was主机hosts文件,把 IP - Hostname (db的IP地址及主机名)写入到这个文件,绕过操作系统级DNS解析器,这样写入的目的是能够让jdbc连接快速获取主机名,从而保证连接db2能快速返回。
B. was早期版本,早期版本对ipv6支持不是很完善,如没有需要使用ipv6,建议这样设置java虚拟机—>通用jvm参数中 添加-Djava.net.preferIPv4Stack=true能确保was只使用ipv4,从而防止调用Inet6AddressImpl 函数实现。




