PHP服务器端守护进程怎么实现MySQL连接池
在启动时创建 10个MySQL连接和10个锁。然后fork出100个worker进程。worker进程随机从pool中取一个连接,先进行加锁操作,然后执行mysql_query。返回后释放锁,让其他进程可以使用此连接。
为什么要加锁呢,原因是mysql_query是一个收发包的过程,如果并发执行mysql_query,就会同时有多个进程发出去请求。这时候没办法区分到底哪个回包是对应的。mysql_query函数会直接抛出致命错误,并切断连接。
另外最好使用mysql_pconnect。避免子进程结束时执行mysql_close破坏此连接,其他子进程也没法用这个连接了。
这里的随机取也可以继续改进一下,使用共享内存来做一个忙闲区分。当执行mysql_query前将此连接设为忙。其他worker取连接时,判断为忙的话跳过此连接。
用下面的代码演示一下。
<?php
for($i = 0; $i < 1; $i ++)
{
$db = new mysqli("localhost", "root", "root", "test");
$lock = fopen("/tmp/mysql_lock.txt", 'w+');
if ($db->connect_errno)
{
printf("Connect failed: %s\n", $db->connect_error);
exit();
}
}
for($i = 0; $i < 5; $i++)
{
if(pcntl_fork() > 0)
{
continue;
}
if (flock($lock, LOCK_EX))
{
$result = $db->query('show tables');
}
flock($lock, LOCK_UN);
if (empty($result))
{
print('Invalid query: ' . $db->error."\n");
}
else
{
while ($row = $result->fetch_assoc())
{
echo "#".posix_getpid(),"\t";
var_dump($row);
echo "\n";
}
$result->close();
}
sleep(1000);
exit;
}
sleep(1000);
分类: PHP