swoole mysql 连接池

33 篇文章 0 订阅
21 篇文章 0 订阅

懵懵懂懂的 去年开始接触一部分java程序员 才知道进程的概念 单进程的php 在mysql没有连接池的情况下  确实慢了很多

于是查询了半天 找到了韩天峰大神开发的 swoole ,敬仰10分钟 感觉 好多困扰自己的问题 一下就解决了 包括之前的 多进程发邮件 http://blog.csdn.net/zhaodongku/article/details/79570428 


今天找了片文章,特别感谢 @水晶依恋 的http://blog.csdn.net/qq_28602957/article/details/78305039 

自己也搭建了下


测试说明 已经提前往数据库添加 id 和num 字段 num字段为随机数 1111-9999  

添加了 一共20万条数据,然后分别用swoole的简单连接池 和 mysql 直接去查询数据,然后 json_encode(数据).time 来对比查询效率

client.php

$client = new swoole_client(SWOOLE_SOCK_TCP);//创建swoole tcp客户端

$client->connect('127.0.0.1', 9503, 10) or die("连接失败");//连接server
$num=rand(1111,9999);
echo  $sql = "SELECT * FROM `test`  where num  =  $num ;";

$client->send($sql);

$data = $client->recv();

$time=date("Y-m-d H:i:s",time());
$data=json_encode($data).$time; 

file_put_contents("./test.txt", $data.PHP_EOL, FILE_APPEND);

$client->close();


my.php(普通mysqli查询)


$conn = @mysqli_connect("127.0.0.1", "root", "root", "lingchen");


$num=rand(1111,9999);
echo  $sql = "SELECT * FROM `test`  where num  =  $num ;";

if($conn){
    //mysqli_select_db($conn,"hulk");
    $res=mysqli_query($conn,$sql);
    $row=mysqli_fetch_assoc($res);
  


    $time=date("Y-m-d H:i:s",time());
$data=json_encode($row).$time; 


file_put_contents("./test1.txt", $data.PHP_EOL, FILE_APPEND);
   
}else{
    echo "ERROR";
}


在服务器   php server.php 可以打印一些信息

server.php


 


<?php


$serv = new swoole_server('127.0.0.1', 9503);
$serv->set(array(
    'worker_num' => 20, //worker进程数量
    'task_worker_num' => 10, //task进程数量 即为维持的MySQL连接的数量
));
echo 111;


function my_onReceive($serv, $fd, $from_id, $data)
{
    echo "收到数据".$data.PHP_EOL;
    //taskwait就是投递一条任务,这里直接传递SQL语句了
    //然后阻塞等待SQL完成,并返回结果
    $result = $serv->taskwait($data);
    echo "任务结束".PHP_EOL;
    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");//如果返回的是false,则说明taskwait等待超时,可以设置相应的等待超时时间
    }
}


function my_onTask($serv, $task_id, $from_id, $sql)
{
    echo "开始做任务 task id:".$task_id.PHP_EOL;
    static $link = null;
    HELL:
    if ($link == null) {
       $link = @mysqli_connect("127.0.0.1", "root", "root", "lingchen");
        if (!$link) {
            $link = null;
            $serv->finish("ER:" . mysqli_error($link));
            return;
        }   
    }   
    $result = $link->query($sql);
    if (!$result) { //如果查询失败了
        if(in_array(mysqli_errno($link), [2013, 2006])){//错误码为2013,或者2006,则重连数据库,重新执行sql
                $link = null;
                goto HELL;
        }else{
            $serv->finish("ER:" . mysqli_error($link));
            return;
        }
    }
    if(preg_match("/^select/i", $sql)){//如果是select操作,就返回关联数组
        $data = $result->fetch_assoc();
    }else{//否则直接返回结果
        $data = $result;
    }
    $serv->finish("OK:" . serialize($data));//调用finish方法,用于在task进程中通知worker进程,投递的任务已完成
    //return "OK:".serialize($data);
}


function my_onFinish($serv, $task_id, $data)
{
    echo "任务完成";//taskwait 没有触发这个函数。。
    echo "AsyncTask Finish:Connect.PID=" . posix_getpid() . PHP_EOL;
}


$serv->on('receive', 'my_onReceive');
$serv->on('task', 'my_onTask');
$serv->on('Finish', 'my_onFinish');


$serv->start();//启动server


测试工具 ab

请求次数 5000次

结果:

单进程php                             17:18:37  17:21:32    不到2分55

mysql连接池                           17:17:21   17:18:06  45秒   

                                            17:23:49  17:24:21   32秒  

                  一万条请求            17:48:46   17:49:48 





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值