卷曲5000度的最快方式+;URL并将其插入php中的mysql数据库?

卷曲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 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);
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连接