现象描述:
1、web页面访问异常慢,有部分页面抛如下错误:
2、日志报错:
2017-02-23 16:53:53 53 [filter.CheckMallCpDetailFilter]-[ERROR] - weblogic.jdbc.extensions.PoolLimitSQLException: weblogic.common.resourcepool.ResourceLimitException: No resources currently available in pool livebos to allocate to applications, please increase the size of the pool and retry..
weblogic.jdbc.extensions.PoolLimitSQLException: weblogic.common.resourcepool.ResourceLimitException: No resources currently available in pool livebos to allocate to applications, please increase the size of the pool and retry..
at weblogic.jdbc.common.internal.JDBCUtil.wrapAndThrowResourceException(JDBCUtil.java:252)
at weblogic.jdbc.pool.Driver.connect(Driver.java:142)
at weblogic.jdbc.jts.Driver.getNonTxConnection(Driver.java:658)
at weblogic.jdbc.jts.Driver.connect(Driver.java:127)
at weblogic.jdbc.common.internal.RmiDataSource.getConnectionInternal(RmiDataSource.java:533)
at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:498)
at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:491)
at com.apex.crm.JDBCConnection.getDB(JDBCConnection.java:99)
at filter.CheckMallCpDetailFilter.isAllowed(CheckMallCpDetailFilter.java:64)
at filter.CheckMallCpDetailFilter.doFilter(CheckMallCpDetailFilter.java:152)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
3、weblogic控制台可以看出,server2的某数据源负载过大
分析过程:
1、综合以上3种信息,可以得出问题出在weblogic的数据库连接池
2、由 No resources currently available in pool livebos to allocate to applications, please increase the size of the pool and retry..可以看出,数据库连接池需要增大。
但是,考虑到该环境是测试环境,并没有很大并发访问,怎么会出现150个连接线程全部被占用的情况?所以认为,问题可能出现在代码里面。
3、使用jstack打印出server2的线程堆栈,统计信息如下:
4、进一步分析线程堆栈文件,发现处于TIMED_WAITING (on object monitor)的30个线程中,有11个线程在等待数据库资源
"[ACTIVE] ExecuteThread: '23' for queue: 'weblogic.kernel.Default (self-tuning)'" daemon prio=10 tid=0x00007f05a0011800 nid=0x37aa in Object.wait() [0x00007f04678c7000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at weblogic.common.resourcepool.ResourcePoolImpl.reserveResourceInternal(ResourcePoolImpl.java:554)
- locked <0x00000003018eeb78> (a weblogic.jdbc.common.internal.GenericConnectionPool)
at weblogic.common.resourcepool.ResourcePoolImpl.reserveResource(ResourcePoolImpl.java:343)
at weblogic.common.resourcepool.ResourcePoolImpl.reserveResource(ResourcePoolImpl.java:330)
at weblogic.jdbc.common.internal.ConnectionPool.reserve(ConnectionPool.java:469)
at weblogic.jdbc.common.internal.ConnectionPool.reserve(ConnectionPool.java:363)
at weblogic.jdbc.common.internal.ConnectionPoolManager.reserve(ConnectionPoolManager.java:125)
at weblogic.jdbc.common.internal.ConnectionPoolManager.reserve(ConnectionPoolManager.java:158)
at weblogic.jdbc.pool.Driver.connect(Driver.java:132)
at weblogic.jdbc.jts.Driver.getNonTxConnection(Driver.java:658)
at weblogic.jdbc.jts.Driver.connect(Driver.java:127)
at weblogic.jdbc.common.internal.RmiDataSource.getConnectionInternal(RmiDataSource.java:533)
at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:498)
at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:491)
at com.apex.crm.JDBCConnection.getDB(JDBCConnection.java:99)
at filter.CheckMallCpDetailFilter.isAllowed(CheckMallCpDetailFilter.java:64)
at filter.CheckMallCpDetailFilter.doFilter(CheckMallCpDetailFilter.java:166)
并且,处于RUNNABLE的15个线程和其他状态的线程都没有持有数据库连接,也就是说,应用代码里面不存在数据库连接泄漏的情况。
5、由现象3中大量的失败请求计数和保留请求计数,初步推断出问题可能出现在数据库端
6、数据库专家检查数据库,发现有一张表处于死锁状态,解锁后,重启server2服务器,服务正常运行
7、向大神请教了查看oracle数据库锁表信息的sql语句如下
Select substr(nvl(s.USERNAME,'sys'),1,9) "用户名",
nvl(s.TERMINAL,'None') "终端",
decode(l.LMODE,
1,'No Lock',
2,'Row Share',
3,'Row Exclusive',
4,'Share',
5,'Share Row Exclusive',
6,'Exclusive',
null) "持有锁",
decode(l.REQUEST,
1,'No Lock',
2,'Row Share',
3,'Row Exclusive',
4,'Share',
5,'Share Row Exclusive',
6,'Exclusive',
null) "申请锁",
/* U1.NAME||'.'|| */
SUBSTR(T1.NAME,1,13) "表名",
substr(l.SID||','||s.SERIAL#,1,10) "SID.SERIAL"
FROM V$LOCK L,
V$SESSION S,
SYS.USER$ U1,
SYS.OBJ$ T1
where l.sid=s.sid
and t1.obj#=decode(l.id2,0,l.id1,l.id2)
and u1.user#=t1.owner#
and U1.NAME != 'SYS'
and s.TYPE != 'BACKGROUND'
order by 1,2,5;