4

我正在使用 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 个不同的连接。

这是真的吗?

谢谢大家。

4

3 回答 3

4

你在错误的地方寻找好处;使用持久连接不会像在您的测试中那样帮助执行单个 php 脚本 - 它有助于处理一系列请求。

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

当你的线程关闭时,你应该在 netstat 中列出 15 个连接,就像你做的那样。

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

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

于 2013-05-17T13:07:29.567 回答
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)

你可以阅读更多关于mysql 和 mysqli 的中文持久连接的一些区别的信息

于 2013-08-16T02:54:21.287 回答
0

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

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

在 Apache 中,我相信StartServers指令是相关的,然后对于每个运行的子服务器进程,您有Th​​readsPerChild线程正在运行,每个线程都将使用来自其各自父级的持久链接。

我的猜测是,如果您使用的是 Apache,那么您有 15 个子进程正在运行,并且每个子进程都有自己的线程。这就是为什么您会看到 15 个持久连接。

希望有帮助。

于 2012-07-25T21:48:02.137 回答