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 次 |
| 最近记录: |