PHP的数据库连接池始终败兴都是一个困难,非常多从PHP语言转向Java的项目,大都数原由都是由于Java有更好的连接池实现。PHP的MySQL扩展供给了长连接的API,但在PHP设备数量较多,规模很强的状况下,mysql_pconnect非但不可节约MySQL资源,反而会加剧数据库的负荷。
假设有100台PHP的应用服务器,每一个设备必须起步100个apache或fpm工作进程,那每一个进程都会产生一个长连接到MySQL。这一共会产生1万个My SQL连接。大众都晓得MySQL是每一个连接会占用1个线程。那MYSQL就必须创建1万个线程,这般海量的系统资源被浪费在线程间上下文切换上。而你的业务代码中并不是所有地区都在做数据库操作,因此这个便是浪费的。
连接池就区别了,100个worker进程,公用10个数据库连接就可,当操作完数据库后,立即释放资源给其他worker进程。这般就算有100台PHP的服务器,那亦只会创建1000个MySQL的连接,完全能够接受的。
以前确实无好的办法来处理此问题的,此刻有了swoole扩展,利用swoole供给的task功能能够很方便做出一个连接池来。
代码如下:
$serv = new swoole_server("127.0.0.1", 9508);
$serv->set(array(
worker_num => 100,
task_worker_num => 10, //MySQL连接的数量 ));
function my_onReceive($serv, $fd, $from_id, $data)
{
//taskwait便是投递一条任务,这儿直接传递SQL语句了
//而后阻塞等待SQL完成 $result = $serv->taskwait("show tables");
if ($result !== false) {
list($status, $db_res) = explode(:, $result, 2);
if ($status == OK) {
//数据库操作成功了,执行业务规律代码,这儿就自动释放掉MySQL连接的占用 $serv->send($fd, var_export(unserialize($db_res), true) . "\n");
} else {
$serv->send($fd, $db_res);
}
return;
} else {
$serv->send($fd, "Error. Task timeout\n");
}
}
function my_onTask($serv, $task_id, $from_id, $sql)
{
static $link = null;
if ($link == null) {
$link = mysqli_connect("127.0.0.1", "root", "root", "test");
if (!$link) {
$link = null;
$serv->finish("ER:" . mysqli_error($link));
return;
}
}
$result = $link->query($sql);
if (!$result) {
$serv->finish("ER:" . mysqli_error($link));
return;
}
$data = $result->fetch_all(MYSQLI_ASSOC);
$serv->finish("OK:" . serialize($data));
}
function my_onFinish($serv, $data)
{
echo "AsyncTask Finish:Connect.PID=" . posix_getpid() . PHP_EOL;
}
$serv->on(Receive, my_onReceive);
$serv->on(Task, my_onTask); $serv->on(Finish,
|