**fjin原创** 来源: http://www.blogjava.net/fjin/archive/2011/03/22/346685.html

 

</p>

  </p>

        问题的描述在上面,我这里简单复述一下这个问题:当应用被加载的时候,会有大量的请求被触发,这时可以看到连接数迅速增长到110,活动连接数也达到102。但后来发现,连接数迅速下降到40,同时看到“Failed Reserve Request Count”迅速增长。同时Oracle DBA也报告说很多新的连接被建立(远大于之前的110)。应用开始抛出“XX connection pool is disabled”的错误。一段时间以后,连接池自我恢复完毕,连接重新回到110,但DBA看到连接此时没有减少,任然维持在240左右。 

        直觉上来看,这个问题应该是连接池临时disable或者flush导致的,而不是shrink导致(从后面的pool disable也能看出来,pool是被disable而不是shrink了),可以通过netstat看一下db端的连接状态,应该很多处于close_wait状态,记连接关闭请求由weblogic端发起,但截至问题发生的时刻,连接本身尚未关闭。为什么会出现连接池临时disable的状况呢?问题根源在于test-connections-on-reserve的设定后,当某个连接的idle时间超过</span></span></span></span></span></span></span></span></span>SecondsToTrustAnIdlePoolConnection 后,这个连接在返回客户端之前,会进行连接测试。测试之前,WLS首先会调用checkHang()来检查之前的连接测试是否存在挂起的现象,如果挂起,我们需要disable整个connection pool,同时重新初始化这个连接池。那么什么情况下,连接测试会被视为挂起呢? </p>

        </span></span></span></span></span></span></span>当一个连接被测试后(在测试结果返回之前),测试记录(TestRecord)会被记录到一个叫做currentlyRunningTests的TreeSet变量中,当测试返回后,无论结果成功与否,这个record都会被从currentlyRunningTests中删除。在连接被测试之前,checkHang()被调用,checkHang的逻辑如下:
</span></span></span> </p>

1  // check and process test hang
2  private void checkHang() throws ResourceDisabledException
3

        当currentlyRunningTests中的记录数超过五条的时候,第六条会被返回,否则不会返回测试记录,即suspectHang将返回false。而当记录数超过五条的时候,我们会拿第六条记录作为checkHang的样本。每次连接测试成功后,wls会将这一次的测试时间作为一个样本时间,记录到一个successfulTestTimes数组中,这个数组最多维护10条记录,然后wls会这10个时间中,最长的那个作为样本测试时间。最后再用这个样本测试时间*TYPICAL_TIME_FACTOR(hard-coded value is 1.2)作为连接返回时间,如果我们的样本record测试时间已经超过样本测试时间,那么suspectHang将返回true, 否则返回false。如果suspectHang返回true,当前线程进入for循环,sleep20次(SLEEP_COUNT)后,如果测试仍然没有返回,且currentlyRunningTests中前五个测试记录也没有返回的话,那么这个测试将会被视为测试挂起,这个pool就会被disable。可能引起这问题的条件是:之前的数据库性能很好,测试都能够迅速返回,可能测试耗时都是毫秒级的。突然某一时刻,数据库性能急剧下降,导致测试耗时很长(当然包括前面的五条测试记录)。WLS以之前的测试时间作为样本时间来衡量此时此刻的测试结果,在数据库性能下降、测试响应慢的时候,很容易被当成测试挂起来处理(即disable整个pool)。 </p>

</span></span></span></span></span></span></span></span></font>        于是客户端看到了pool被disable的现象,那么Pool什么时候会被重新初始化呢,pool中有一个Healh Maintainece Task,每隔五秒,这个task会启动一次,用于检查那些被disabled的pool,如果连接测试通过,那么这个Pool会被重新enable。 </p>

        这个实现方式不是很好,于是10.3.4中对这块做了重新设计。我们现在看看10.3.4中是如何实现的吧!
        10.3.4引入了一个可配置变量weblogic.resourcepool.max_test_wait_secs,默认为10秒,如果通过-Dweblogic.resourcepool.max_test_wait_secs将它设为0,那么连接测试的时候,将不再做checkHang。如果这个值不是0,那么checkHang的最长等待时间将是这个指定的值,而不再像10.3.0中,最长等待时间为样本时间*20。同时修改了TYPICAL_TIME_FACTOR,这个值由1.2变成了10,这个值得修改对suspectHang有一定影响,但影响不大,这个参数也是硬编码的,客户不能对它进行配置。这两个参数中,对checkHang影响比较大的还是weblogic.resourcepool.max_test_wait_secs,所以如果碰到类似问题,可以通过适当的修改这个值来解决问题。
</span></span></span></span></span>   &#
160;  
</span></span></span></font></span></span></font></span></font></span></font></span></span></font></span></font></span>

转载请注明:WebLogic Android 博客 » WLS10.3.0中,连接测试导致的connection pool shrinking(disabling)问题分析[转]