mod_perl Apache::DBI

mod_perl Apache::DBI

mod_perl Apache::DBI
1
请教高手,关于mod_perl Apache::DBI的persistent connection


我看了一下手册,想确定一下在persistent connection情况下mysql的连接数的变化情况,作了以下测试:
写了一个test.cgi脚本,如下:
use Apache::DBI;
use CGI::Carp qw(fatalsToBrowser);
use CGI qw/:standard/;

use DBI;
my @dbhs;

print header;
print "pid $$\n";

foreach (0 .. 59) {
$dbhs[$_] = DBI->connect("DBI:mysql:mydb:127.0.0.1","user","passwd");
print $_,"\n";


}


sleep 60;


foreach (@dbhs) {
$_->disconnect;

}



在linux firefox下访问http://host/test.cgi,同时在mysql下运行
show processlist;
发现我同时发送30个请求与只发送一个请求的结果是一样的,mysql显示有61个连接(其中一个是mysql client.),当最后一个请求结束后,mysql的连接数立即变为1,
然后我将上面的循环去掉,只连接一个dbh,结果是发送30个请求时mysql显示有2个连接。当最后一个请求结束后,mysql的连接数立即变为1,

然后我用linux下的w3c程序来同时访问上述地址,结果却和上面不一致:并发发送几个请求就会产生几个连接.mysql 的连接数与并发的个数一致(当然要加1),即请求增加一个,就会产生一个连接,请求结束一个,就会减少一个连接


我又用ab -c 10 http://host/test.cgi试了一下,结果与用w3c一致,显示有11个连接.

请问对上述结果作何解释?
我原来以为:
无论有多少个请求,每个请求有多少个dbh,都应该只有一个连接吧?因为所请求的连接的参数都一样呀,
当用firefox请求时,即便连接数应该为61,那么请求结束后也应该继续保持这个连接,而不应该立刻变为1呀

用w3c与ab就更不行了,这和不用persistent connection有什么两样???

另外,连接数与apache process 和thread有什么关系吗?
谢谢
"然后我将上面的循环去掉,只连接一个dbh,结果是发送30个请求时mysql显示有2个连接。当最后一个请求结束后,mysql的连接数立即变为1"

上面这样才该是 Apache::DBI 的 persistent 行为,不过我已经没有碰 mod_perl 东西很久,没什么地方可以测试你的发现。Apache::DBI 开发已经很成熟了,我想大概是其他方面的影响造成这个结果的。
今天我又在自己机器上测试了一下
上面是我在公司服务器上测的,我怀疑它的配置有问题,因此现在我又在自己的机器上测了一下。
我的apache2的配置基本就是缺省配置,用的MPM是worker.c
我测试的结果是
mysql 的连接数大约为apache 并发数的1/5,即当我用ab -c 150 http://localhost/cgi-bin/test.cgi时,
mysql 的连接数为30,不知道这个结论是怎么回事
我理解的apache::DBI的行为应该是:
配置中每个process有25个thread,因此应该有150/25=6个子进程,而Apache::DBI中说的好像是在同一个进程内,dbh是共享的,那么应该就是6个进程6个dbh,但现在是30个,这个结果如何解释?
我现在有一个项目,要计算一下是用永久联接还是用非永久联接dbh 的数目比较少,因此比较关心这个问题,想知道apache请求并发数与进程,线程,dbh数目的关系,
请大家指教.




   

我看了一下这个网页,里面.
我看了一下这个网页,里面大体解释了这个现像
http://www.apachetutor.org/dev/reslist
但我现在想知道的是,为什么这个值是5(即每5个threads共享一个dbh)而不是别的?这个值在哪里定义的?
从apache手册或mod_perl哪里可以看到正式的说明?
如果不用Apache::DBI
如果去掉PerlModule Apache::DBI,测试结果如下
#use Apache::DBI;
use CGI::Carp qw(fatalsToBrowser);
use CGI qw/:standard/;

use DBI;
my @dbhs;
my $num = 1;
print header;
print "pid $$\n";

foreach my $i (1 .. $num) {
$dbhs[$i] = DBI->connect("DBI:mysql:global:127.0.0.1","chylli","3843054");
foreach my $count (1 .. 3){
$dbhs[$i]->do("show processlist");
sleep 1;
}

}

export conc = 20; ab -c $conc http://localhost/cgi-bin/test.cgi

当$num = 1时,dbh数量与并发数仍然为1:5 (此处的结论并不精确,因为它们的关系可能与ThreadsPerChild的mod有关)
当$num = 2或者其它数值时dbh数量与并发数无法确定线性关系(至少我没判定,),但可以肯定的是连接数比$num * $conc 要少,也就是说process内存在共享dbh,由于即便我们不用Apache::DBI我们也可以用别的办法保证在同一个会话中对同一个database的连接保证唯一,这个结论我不再关心

值得一提的是,当ab 运行完毕后mysql的connect迅速变为0

结论(针对apache2):
1. Apache::DBI的作用是在同一个会话内,无论有多少次对database的请求连接,都只有惟一一个dbh,并且一个会话结束后,如果此thread不关闭,则dbh仍然保留,这就避免了建立所需要的时间
2. 即便不用Apache::DBI,同一个process的threads仍然会共享连接,但对同一个会话,如果多少请求同一个database的连接,则会产生多个dbh连接
3. threads与connection之间数目大约为5:1,但我不清楚是同一个process会产生最多5个连接(对同一database)还是每5个threads产生一个连接,也就是说,现在ThreadsPerChild为25,数目为5:1,但如果为50的话,是5:1还是10:1 ??我将ThreadsPerChild改为50,数目为10:1,也就是说每一个process会产生5个连接。