首页 > PHP > PHP服务器端守护进程怎么实现MySQL连接池

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 标签: