Sri*_*lla 7 javascript php python perl curl
我有1000个源URL位于MySQL数据库表中.我需要每隔2分钟向所有这些网址发送一个http请求.我写了一个PHP脚本来做,但脚本需要5分30秒才能运行.
我希望能够在一分钟内完成所有1000个请求.有没有办法运行多个异步进程来更快地完成工作?任何帮助表示赞赏.提前致谢.
由于您的问题是关于发送http请求,而不是真正ping,您可以使用Grequests(请求 + gevent)轻松快速地完成(根据我的经验,几秒钟的url请求):
import grequests
urls = [
    'http://www.python.org',
    'http://python-requests.org',
    'http://www.google.com',
]
rs = (grequests.get(u) for u in urls)
grequests.map(rs)    # [<Response [200]>, <Response [200]>, <Response [200]>]
Run Code Online (Sandbox Code Playgroud)
您的Php脚本需要5分钟才能运行,因为它是同步代码,这意味着对于您发送的每个请求,您必须等待响应到达才能发送下一个请求.
这里的诀窍是不要等待(或阻止尽可能多的人调用)响应,而是直接进行下一个请求,你可以轻松地实现它gevent(基于协程)或nodejs.你可以在这里阅读更多内容.
感谢亚历克斯·卢尼克斯的建议。我查找了curl_multi_*并找到了在curl中执行此操作的解决方案,因此我不必对代码进行太多更改。但谢谢其他所有人的回答。这是我所做的:
<?php
require("class.php");
$obj=new module();
$det=$obj->get_url();
$batch_size = 40;
function curlTest2($urls) {
    clearstatcache();
    $batch_size = count($urls);
    $return = '';
    echo "<br/><br/>Batch:";
    foreach ($urls as &$url)
    {
        echo "<br/>".$url;
        if(substr($url,0,4)!="http") $url = "http://".$url;
        $url = "https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=-1&q=".$url;
    }
    $userAgent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)';
    $chs = array();
    for ($i = 0; $i < $batch_size; $i++)
    {
        $ch = curl_init();
        array_push($chs, $ch);
    }
    for ($i = 0; $i < $batch_size; $i++)
    {
        curl_setopt($chs[$i], CURLOPT_HEADER, 1);
        curl_setopt($chs[$i], CURLOPT_NOBODY, 1);
        curl_setopt($chs[$i], CURLOPT_USERAGENT, $userAgent);
        curl_setopt($chs[$i], CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($chs[$i], CURLOPT_CONNECTTIMEOUT, 15);
        curl_setopt($chs[$i], CURLOPT_FAILONERROR, 1);
        curl_setopt($chs[$i], CURLOPT_FRESH_CONNECT, 1);
        curl_setopt($chs[$i], CURLOPT_URL, $urls[$i]);
    }
    $mh = curl_multi_init();
    for ($i = 0; $i < $batch_size; $i++)
    {
        curl_multi_add_handle($mh, $chs[$i]);
    }
    $active = null;
    //execute the handles
    do {
        $mrc = curl_multi_exec($mh, $active);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    while ($active && $mrc == CURLM_OK) {
        if (curl_multi_select($mh) != -1) {
            do {
                $mrc = curl_multi_exec($mh, $active);
            } while ($mrc == CURLM_CALL_MULTI_PERFORM);
        }
    }
    //close the handles
    for ($i = 0; $i < $batch_size; $i++)
    {
        curl_multi_remove_handle($mh, $chs[$i]);
    }
    curl_multi_close($mh);
}
$startTime = time();
$urls = array();
foreach($det as $key=>$value){
    array_push($urls, $value['url']);
    if (count($urls) == $batch_size)
    {
        curlTest2($urls);
        $urls = array();
    }
}
echo "<br/><br/>Time: ".(time() - $startTime)."sec";
?>
Run Code Online (Sandbox Code Playgroud)
这将我的处理时间从 332 秒缩短到 18 秒。该代码可能可以稍微优化,但您已经了解了它的要点。
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           3781 次  |  
        
|   最近记录:  |