page contents

利用swoole多进程减少后端访问时间的方法

swoole的多进程process方法,比curl模拟并发的更加方便一些。所以还是要建议大家学一学swoole。

attachments-2020-06-AbF00p2w5ef1996a66336.png

应用一:请求接口,减少时间

假设我们需要CURL多个地址,例如3个,每个需要1秒,如果我们同步运行至少需要3秒完成,这对用户的体验是非常不好的,我们可以引入swoole的process子进程开启三个进程同时curl则需要1秒处理好。

代码实现:

<?php

echo 'start:' . date("Ymd H:i:s");
$urls = [
    'http://www.baidu.com',
    'http://www.sina.com.cn',
    'http://www.qq.com',
];
//模仿读取(已注销)
/*foreach ($urls as $url) {
    $content = [] = file_get_contents($url);
}*/

//使用swoole的process开启多个子进程
for ($i = 0; $i < 3; $i++) {
    //子进程  use用于传值
    $process = new swoole_process(function (swoole_process $worker) use ($i, $urls) {
        //curl处理
        $content = curlData($urls[$i]);
        //因为下面参数是true所以会输出到管道里
        echo $content . PHP_EOL;
    }, true);
    $pid = $process->start();
    $wokers[$pid] = $process;

}

foreach ($wokers as $process) {
    echo $process->read();
}

function curlData($url)
{
    //模拟消耗1秒
    sleep(1);
    return $url . "success" . PHP_EOL;
}

echo 'end:' . date("Ymd H:i:s");

运行结果如下,确实运行缩短至1秒

v2-1bcadd70ea8ec90fd860c5538bba755c_720w.jpg


应用二:发送邮件和短信

比如,我们要对已知的用户数据进行判断,是否需要发送邮件和短信,如果需要发送则发送。

不使用多进程时,我们首先判断是否发送邮件,如果需要则发送;然后再判断是否需要发送短信,如果需要则发送。如果发送邮件耗时2s,发送短信耗时2s,那么我们完成任务大概需要4s左右的时间。

如果我们使用多线程的话,可以开两个线程,一个用于处理邮件,一个用于处理短信,则耗时一共需要2s左右,处理时间缩短了一半。

下面看详细代码

<?php
$info = array(
    "sendmail"=>1,
    "mailto"=>"12345@qq.com",
    "sendsms"=>1,
    "smsto"=>"123456"
);
echo "start:".date("Y-m-d H:i:s").PHP_EOL;
$mail_process = new swoole_process('sendMail',true);
$mail_process->start();
$sms_process = new swoole_process('sendSMS',true);
$sms_process->start();
//主进程输出子进程范围内容
echo $mail_process->read();
echo PHP_EOL;
echo $sms_process->read();
echo PHP_EOL;
echo "end:".date("Y-m-d H:i:s").PHP_EOL;
//并行函数
function sendMail(swoole_process $worker){
    global $info;
    if($info['sendmail']==1){
        sleep(2);
        $worker->write("send mail to ".$info['mailto']);
    }
}
function sendSMS(swoole_process $worker){
    global $info;
    if($info['sendmail']==1){
        sleep(2);
        $worker->write("send sms to ".$info['smsto']);
    }
}


应用三:网页抓取,循环执行任务,划分多个进程执行

假设我们现在有一个通过curl抓取网页内容的需求,需要抓取10个网页,url地址通过数组读取,每个curl耗时2s。如果我们通过for循环来抓取这10个网页,需要耗时20s,使用多进程我们可以将任务划分成5份,分别由5个进程执行,每个进程抓取2个url,并发执行,共耗时4s,效率提高5倍。

<?php

$url_arr = array();
for ($i=0;$i<10;$i++){
    $url_arr[] = "www.baidu.com?wd=".$i;
}
echo "start:".date("Y-m-d H:i:s").PHP_EOL;
$workers = array();
for ($i=0;$i<5;$i++){
    $process = new swoole_process('getContents',true);
    $process->start();
    $process->write($i);
    $workers[] = $process;
}
//主进程数据结果
foreach ($workers as $process){
    echo $process->read();
    echo PHP_EOL;
}
echo "end:".date("Y-m-d H:i:s").PHP_EOL;
function getContents(swoole_process $worker){
    $i = $worker->read();
    global $url_arr;
    $res1 = execCurl($url_arr[($i*2)]);
    $res2 = execCurl($url_arr[($i*2+1)]);
    echo $res1.PHP_EOL.$res2;
}
function execCurl($url){
    sleep(2);
    return "handle ".$url." finished";
}

执行效果如下:

v2-11726bf9c6d324b1363f2ba27ee08d60_720w.jpg

从上面的例子可以看出:swoole的多进程process方法,比curl模拟并发的更加方便一些。所以还是要建议大家学一学swoole。


attachments-2020-06-qYK0y7ca5ef1997cb9bf7.jpg

  • 发表于 2020-06-23 13:56
  • 阅读 ( 525 )
  • 分类:PHP开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
Pack
Pack

1135 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1316 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章