Tomcat 启动时间过长 Connection has been abandoned PooledConnection

环境:Tomcat ,使用了jndi 连接oracle
现象:生产环境上的tomcat迁移到新的主机上,在新主机上tomcat启动需要长达20分钟,并且过程中会出现以下警告:

08-Jan-2021 13:55:35.374 警告 [Tomcat JDBC Pool Cleaner[1418481495:1610085005364]] org.apache.tomcat.jdbc.pool.ConnectionPool.abandon Connection has been abandoned PooledConnection[oracle.jdbc.driver.T4CConnection@6f4a47c7]:java.lang.Exception
	at org.apache.tomcat.jdbc.pool.ConnectionPool.getThreadDump(ConnectionPool.java:1107)
	at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:744)
	at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:671)
	at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:483)
	at org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:154)
	at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:118)
	at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:107)
	at org.apache.tomcat.jdbc.pool.DataSourceFactory.createDataSource(DataSourceFactory.java:560)
	at org.apache.tomcat.jdbc.pool.DataSourceFactory.getObjectInstance(DataSourceFactory.java:244)
	at org.apache.naming.factory.FactoryBase.getObjectInstance(FactoryBase.java:96)
	at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321)
	at org.apache.naming.NamingContext.lookup(NamingContext.java:839)
	at org.apache.naming.NamingContext.lookup(NamingContext.java:159)
	at org.apache.naming.NamingContextBindingsEnumeration.nextElementInternal(NamingContextBindingsEnumeration.java:117)
	at org.apache.naming.NamingContextBindingsEnumeration.next(NamingContextBindingsEnumeration.java:71)
	at org.apache.naming.NamingContextBindingsEnumeration.next(NamingContextBindingsEnumeration.java:34)
	at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans(GlobalResourcesLifecycleListener.java:132)
	at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans(GlobalResourcesLifecycleListener.java:106)
	at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.lifecycleEvent(GlobalResourcesLifecycleListener.java:81)
	at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123)
	at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:423)
	at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:366)
	at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:759)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
	at org.apache.catalina.startup.Catalina.start(Catalina.java:688)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:342)
	at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:473)

但是比对过tomcat和项目文件和旧主机上的都相同,使用的数据库也是相同的。
原先怀疑是新主机和oracle 之间网络的问题,但是项目经过长时间启动后,使用都正常,也没有报过上述错误。
同时发现项目中oracle driver和所连数据库版本不对应,进行更新后,现象还是发生。

最后在tomcat启动过程,不输出命令的时候,使用jstack 输出线程堆栈,来看看tomcat 在卡的时候再执行什么,再来看看如何处理。

jstack -l tomcat的pid >  ./tomcat_stack.data
# 一般生产环境上不会装 jdk,也可以通过执行以下命令 在tomcat的catalina.log中输出线程堆栈
# kill -3 经过测试不会杀死tomcat 进程,对业务无影响 
kill -3  tomcatpid

发现tomcat 在启动过程中在执行

"main" #1 prio=5 os_prio=0 tid=0x00007f342c00a000 nid=0x8893 runnable [0x00007f3432e1c000]
   java.lang.Thread.State: RUNNABLE
	at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
	at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:928)
	at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1323)
	at java.net.InetAddress.getLocalHost(InetAddress.java:1500)
	- locked <0x00000007715b4100> (a java.lang.Object)
	at oracle.jdbc.driver.T4CTTIoauthenticate.setSessionFields(T4CTTIoauthenticate.java:1431)
	at oracle.jdbc.driver.T4CTTIoauthenticate.<init>(T4CTTIoauthenticate.java:292)
	at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:622)
	at oracle.jdbc.driver.PhysicalConnection.connect(PhysicalConnection.java:782)
	at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:39)
	at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:704)
	at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:319)
	at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:212)
	at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:739)
	at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:671)
	at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:483)
	at org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:154)
	at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:118)
	- locked <0x0000000771401938> (a org.apache.tomcat.jdbc.pool.DataSource)

在jdk中查了以下java.net.Inet6AddressImpl.lookupAllHostAddr,发现是一个native,只能google。

How can we improve performance in java/net/Inet6AddressImpl.lookupAllHostAddr?

A strange UnknownHostException

最后参照,第二个连接中,进行排查,该主机上,确实没有将主机名配置进/etc/hosts上。

# 使用hostname 命令来查看主机
[root@test bin]# hostname
test
# /etc/hosts 里面看看有没有配置主机名和本地地址之间的映射,如果没有的话,追加在后面
# ipv4和ipv6 的本地地址都要配置

127.0.0.1   localhost localhost.localdomain hostname出来的主机名
::1   localhost localhost.localdomain hostname出来的主机名

配置完成后,重启tomcat,启动恢复正常,也没有警告输出了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值