Mysqli持久连接不起作用

时间:2012-07-25 20:18:15

标签: php mysqli persistent-connection

我使用的是PHP 5.4.4,似乎与 mysqli 的持久连接不起作用。特别是,让我们看一下这个脚本:

<?php

$links = array();

for ($i = 0; $i < 15; $i++) {
    $links[] =  mysqli_connect('p:192.168.1.40', 'USER', 'PWD', 'DB', 3306);
}

sleep(15);

然后,当脚本运行时,打开另一个shell并执行:

netstat -an | grep 192.168.1.40:3306
tcp        0      0 192.168.1.6:52441       192.168.1.40:3306       ESTABLISHED
tcp        0      0 192.168.1.6:52454       192.168.1.40:3306       ESTABLISHED
tcp        0      0 192.168.1.6:52445       192.168.1.40:3306       ESTABLISHED
tcp        0      0 192.168.1.6:52443       192.168.1.40:3306       ESTABLISHED
tcp        0      0 192.168.1.6:52446       192.168.1.40:3306       ESTABLISHED
tcp        0      0 192.168.1.6:52449       192.168.1.40:3306       ESTABLISHED
tcp        0      0 192.168.1.6:52452       192.168.1.40:3306       ESTABLISHED
tcp        0      0 192.168.1.6:52442       192.168.1.40:3306       ESTABLISHED
tcp        0      0 192.168.1.6:52450       192.168.1.40:3306       ESTABLISHED
tcp        0      0 192.168.1.6:52448       192.168.1.40:3306       ESTABLISHED
tcp        0      0 192.168.1.6:52440       192.168.1.40:3306       ESTABLISHED
tcp        0      0 192.168.1.6:52447       192.168.1.40:3306       ESTABLISHED
tcp        0      0 192.168.1.6:52444       192.168.1.40:3306       ESTABLISHED
tcp        0      0 192.168.1.6:52451       192.168.1.40:3306       ESTABLISHED
tcp        0      0 192.168.1.6:52453       192.168.1.40:3306       ESTABLISHED

我认为这是一个错误:PHP应该只打开一个持久连接而不是15个不同的连接。

这是真的吗?

感谢所有人。

3 个答案:

答案 0 :(得分:2)

你在错误的地方寻找利益;使用持久连接不会像测试中那样帮助执行单个PHP脚本 - 它可以帮助完成一系列请求。

当您要求mysqli建立持久连接时,它会查找与您的连接详细信息(用户名/密码/等) 匹配的已建立连接池,并且这些连接未被使用。 您的循环要求使用十五个连接,您将获得十五个连接。每个连接都专用于您的线程。

当你的线程关闭时,你应该像netstat一样列出十五个连接。

如果再次运行脚本,您应该看到列出的连接没有变化(即没有建立新的连接)。这就是优势所在 - 在以后的脚本执行中,您可以节省建立连接的开销。

更好的测试是在第一个请求上执行创建一百个持久连接的时间,然后重新运行相同的请求,该请求应该更快,因为它不需要创建一百个新连接。

答案 1 :(得分:1)

mysqli持久连接将在调用mysqli_close后将链接保留到池中。或者运行RSHUTDOWN。所以你可以使用这段代码完成它。

for ($i = 0; $i < 15; $i++) {
    $links[$i] =  mysqli_connect('p:192.168.1.40', 'USER', 'PWD', 'DB', 3306);
    var_dump(mysqli_thread_id($links[$i]));    //make sure they are the same.
    mysqli_close($links[$i])
}
sleep(15);

结果就是这样:

root@cnxct:/home/cfc4n# netstat -antp |grep 3306|grep -v "php-fpm"
tcp        0      0 192.168.61.150:55148    192.168.71.88:3306      ESTABLISHED 5100/php5   
root@cnxct:/home/cfc4n# /usr/bin/php5 4.php 
int(224218)
int(224218)
int(224218)
int(224218)
int(224218)
int(224218)
int(224218)
int(224218)
int(224218)
int(224218)
int(224218)
int(224218)
int(224218)
int(224218)
int(224218)

您可以使用some differences between mysql and mysqli of persistent connection in chinese

阅读更多信息

答案 2 :(得分:0)

如果您运行PHP的服务器API创建多个父进程来运行PHP,这是有道理的。

例如,如果您使用的是FastCGI并将其配置为有15个进程,并且每个进程中有50个子进程,那么在任何给定时间(每个进程1个)和50个子进程中每个进程最多可以有15个持久连接每个相应进程的使用将使用其父进程中的1个持久链接。

在Apache中,我认为StartServers指令是相关的,然后对于每个运行的子服务器进程,运行ThreadsPerChild个线程,每个线程都使用来自各自父节点的持久链接。 / p>

我的猜测是,如果您使用的是Apache,则会运行15个子进程,并且每个进程都有自己的线程。这就是你看到15个持久连接的原因。

希望有所帮助。