2011年9月22日星期四

ADF_109:ADF 调优指南之三:参数“Disconnect Application Module Upon Release”的实验报告

在使用AM Pool时,发现数据库连接消耗的特别快。用户每次访问一个页面,都会新占用一个数据库连接,这显然让人无法接受。
查看了有关AM Pool的设置文档,发现参数“Disconnect Application Module Upon Release”与释放数据库连接有很大关系。

参数Disconnect Application Module Upon Release含义
强制AM 实例每次释放回池中时,同时释放掉其对应的JDBC 连接。默认为false,不选中。
好处是每次AM实例不用再从数据库连接池拿连接,而且连prepared statements也可以直接拿来就用。

为了进一步搞清楚问题所在,获得最佳性能,我做了如下实验:
为了最准确的监控数据库连接数,使用如下SQL语句:
conn sys/welcome1 as sysdba;
select count(sid),username from v$session group by username;

实验1. 全部使用默认值

现象:每访问一次页面,数据库连接都增加一个。手工测试了10次,数据库连接增加到了11个。
解释:用户每访问一次页面,都会从AM Pool中获取一个实例,使用完毕后(即Request请求结束后),AM实例会释放回Pool中,但该AM实例所关联的数据库连接并没有释放(方便下次直接使用,不用再从数据库池中获取)。
由于数据库连接池默认很高:4096,所以在达到这个数字前,数据库连接会持续增加。

实验2. 选中Disconnect Application Module Upon Release,其它设置默认。

现象:每访问一次页面,数据库连接都增加一个。手工测试了10次,数据库连接始终为2个。
解释:用户每访问一次页面,都会从AM Pool中获取一个实例,使用完毕后(即Request请求结束后),AM实例会释放回Pool中,同时强制释放该AM实例所关联的数据库。
不好的地方是下次需要数据连接时,需要重新从数据库池中获取。

实验3. 改动参数设置见下图,其它设置默认。
Idle Instance Timeout:设置为1分钟
Pool Polling Interval:设置为30秒
Maximum Instance Time to Live:设置为2分钟。

现象:开始时每访问一次页面,数据库连接都增加一个。手工持续测试了10次,占用数据库连接数达到12个。
经过大约5分钟后,再次手工测试了10次,所占用数据库连接数依然保持达到12个。
这个和我想象的有出入,我以为经过5分钟后,所有的数据库连接都应该释放了,难道是因为AM Pool的最大值太大了,所以总要保留一些AM实例备用?
那我减少AM Pool的最大值,是不是就会把多余的AM实例释放了? 实验4将验证这一猜想。
解释:AM实例不活动时间超过1分钟后,将被标记为“可以清除”,并在30秒后被清除。
值得注意的是,即使AM实例被清除了,它依然关联着一个数据库连接,直到超过了AM的最大生存时间:2分钟后,才释放其所关联的数据库连接。

实验4. 改动了一些有关AM Pool Size的参数,见下图,其它设置与实验3一样。

现象:开始时每访问一次页面,数据库连接都增加一个。手工持续测试了10次,占用数据库连接数最高达到5个。继续测试,仍然是5个。
解释:至于为何是数字5,经多次实验,发现其实与Maximum Available Size参数值无关,这应该是AM Pool优化算法的自然结果。
用5个数据库连接就可以为多个用户提供访问,这才是我们期待的结果。

经过以上实验,结论如下:
(1)Disconnect Application Module Upon Release 参数默认不选中是有利于性能优化的。
(2)参数Idle Instance Timeout、Pool Polling Interval、Maximum Instance Time to Live 应该配合使用。
基本原则是:Maximum Instance Time to Live >Idle Instance Timeout + Pool Polling Interval(否则还没等AM Pool标记清除之前,AM实例就已经被清除了)。
至于何种组合为最优,需要做性能测试之后,比较之后得出。
(3)每个AM 池的设置可以根据自身情况有所不同。
如果AM的调用时间比较长,可以适当增大Maximum Instance Time to Live;Maximum Pool Size 基本接近或略高于用户并发数的峰值;
如果用户并发数很高,可以适当减小Maximum Instance Time to Live,便于回收AM 实例和数据库连接;
对于操作频繁,但事务较小的AM,可以适当增大Idle Instance Timeout、Pool Polling Interval,尽量直接重用AM实例,无需重新获取。
(4)ADF自带的数据库连接池一般不用于生产环境。在生产环境下,应该使用JDBC Datasource的方式,使用WLS的数据库连接池来管理。基本原则是数据库连接池的最大值=AM Maximum Pool Size。

实验说明
本测试是手工测试,参数值的设定仅用于考证Disconnect Application Module Upon Release及相关参数的含义,不能作为生产环境下的参数设置的依据。
生产环境下的参数设置应该做完一系列的性能测试后,逐步调优各项参数,比较之后得出。
本来想用Oracle Application Test Suite 来做压力测试,但安装使用后,发现我的机器根本承受压力测试,呵呵。

参考文献:
1. http://andrejusb.blogspot.com/2010/02/optimizing-oracle-adf-application-pool.html

没有评论: