卷曲5000度的最快方式+;URL并将其插入php中的mysql数据库?
我使用php curl从api获取数据 第一个url返回50个url,这50个url中的每一个都返回500个结果,然后返回下一个url,直到没有更多结果为止 我目前使用的代码需要5个多小时才能完成,因为5000多个http请求中有200多万条记录要插入mysql 目前我正在使用类从petewarden-> 这是我的完整代码:卷曲5000度的最快方式+;URL并将其插入php中的mysql数据库?,php,mysql,curl,pdo,Php,Mysql,Curl,Pdo,我使用php curl从api获取数据 第一个url返回50个url,这50个url中的每一个都返回500个结果,然后返回下一个url,直到没有更多结果为止 我目前使用的代码需要5个多小时才能完成,因为5000多个http请求中有200多万条记录要插入mysql 目前我正在使用类从petewarden-> 这是我的完整代码: <?php ini_set('memory_limit', '3000M'); ini_set('max_execution_time', 15000); requi
<?php
ini_set('memory_limit', '3000M');
ini_set('max_execution_time', 15000);
require_once('parallelcurl.php');
$host = "localhost";
$user = "user";
$pass = "pass";
$dbname = "db";
try {
# MySQL with PDO_MYSQL
$DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
}
catch(PDOException $e) {
echo $e->getMessage();
}
$table="table";
$nextUrl = 0;
function httpGet($url)
{
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
$output=curl_exec($ch);
curl_close($ch);
return $output;
}
$html = httpGet("https://url1.com");
$arr = json_decode($html, true);
$curl_options = array(
CURLOPT_RETURNTRANSFER => true,
);
$max_requests = 20;
$parallel_curl = new ParallelCurl($max_requests, $curl_options);
foreach ($arr['apiGroups'] as $key => $category) {
$getUrl = $category['availableVariants']['get'];
$parallel_curl->startRequest($getUrl, 'on_request_done');
while ($nextUrl) {
$parallel_curl->startRequest($nextUrl, 'on_request_done');
}
}
function placeholders($text, $count=0, $separator=","){
$result = array();
if($count > 0){
for($x=0; $x<$count; $x++){
$result[] = $text;
}
}
return implode($separator, $result);
}
// This function gets called back for each request that completes
function on_request_done($content, $url, $ch) {
global $DBH, $parallel_curl, $table, $nextUrl;
$arr = json_decode($content, true);
$j=0;
foreach ($arr['productInfoList'] as $key => $item) {
$title = $item['productBaseInfo'];
$url = $item['productUrl'];
$img = $item['imageUrls']['275x275'];
$price = $item['sellingPrice']['amount'];
$pid = $item['productId'];
$selarr[$j] = array('title' => $title, 'url' => $url, 'imgurl' => $img, 'price' => $price, 'productid' => $pid);
$j++;
}
$datafields = array('title' => '', 'url' => '', 'imgurl' => '', 'price' => '', 'productid' => '' );
$insert_values = array();
foreach($selarr as $d){
$question_marks[] = '(' . placeholders('?', sizeof($d)) . ')';
$insert_values = array_merge($insert_values, array_values($d));
}
$DBH->beginTransaction(); // also helps speed up your inserts
$sql = "INSERT INTO $table (" . implode(",", array_keys($datafields) ) . ") VALUES " . implode(',', $question_marks);
$stmt = $DBH->prepare ($sql);
try {
$stmt->execute($insert_values);
} catch (PDOException $e){
echo $e->getMessage();
}
$DBH->commit();
if($arr['nextUrl']) {
$nextUrl = $arr['nextUrl'];
}
else {
$nextUrl = 0;
}
}
$parallel_curl->finishAllRequests();
?>
生成同一PHP脚本的多个实例(从CLI运行),并使用集中队列管理URL上不重叠的作业 我通常使用redis作为队列来实现这一点,您甚至可以考虑使用像这样的现成库 它应该很容易实现
// pseudocode, in your jobs
$batch = $queue->getFirstAvailableBatchOfUrls();
// Do your stuff
// put again in the queue if errors occurs...
if($status == PROCESS_DONE_OK) {
$batch->markAsDone()
} else {
$batch->putAgainInQueue()
}
每秒100多个请求,不是很快吗?您需要找出瓶颈,但我猜您需要更多带宽。请尝试像德国的Gearman这样的job server,但完成每个请求需要5个小时以上的时间。每个请求的大小是1-2mbSo要澄清,您是发出了200万个http请求,还是5000个?如果是前者,那么你很可能达到了你的网络极限(大约每秒110个请求)。好吧,那么你需要找出瓶颈在哪里。您的代码不是那么容易理解,但是您可以先将URL的数量减少到一个示例集(比如500个istead,5000个),然后简单地注释数据库保存,看看需要多长时间。如果时间接近30分钟(5小时/10),那么您就知道数据库不是瓶颈。他的代码已经在使用curl_multi_exec,并行运行请求-可能是他的限制bandwidth@Steve我有一个来自HostGator的专用服务器有一个专用服务器并不保证你有一个专用的T3连接