导入大量数据时如何避免超时?

时间:2015-09-09 作者:hannit cohen

我需要从外部服务器导入目录数据。数据按类别排列,然后按项目排列。

API需要以下调用:1。获取类别2。获取类别项目3。获取项目数据

此任务通过使用cron作业每天工作一次。该目录包含约5000个项目。

项目导入封装为3个文件:1。获取猫-获取所有类别2。获取类别项目-获取所有项目,创建每个项目(cpt),然后调用33。获取项目信息-更新项目数据(自定义字段)

无论我做什么,我总会遇到504网关超时错误。

我怎样才能绕过它?

脚本1:

    <?php 
/* Short and sweet */
define(\'WP_USE_THEMES\', false);
require(\'./wp-blog-header.php\');
set_time_limit(600);

$processed_cats = array();
$processed_items = array();

$cats = get_terms( \'svod_cat\', array(\'hide_empty\' => false));
foreach ($cats as $cat) {
    if (get_field(\'disabled\', \'svod_cat_\'.$cat->term_id))
        continue;

    $cat_id = get_field(\'cat_id\', \'svod_cat_\'.$cat->term_id);
    $curl = curl_init();
    curl_setopt ($curl, CURLOPT_URL, \'http://example.com/import_cat.php?cat_id=\'.$cat->term_id);
    curl_exec ($curl);
    curl_close ($curl);
    echo $res."<br/>";
}
svod_update_disabled_items($processed_items);


?>
脚本2:

    <?php 
/* Short and sweet */
define(\'WP_USE_THEMES\', false);
require(\'./wp-blog-header.php\');
set_time_limit(3600);
error_reporting(E_ERROR | E_WARNING | E_PARSE);

$wp_cat = $_GET[\'cat_id\'];

function svod_get_items_list($cat) {
    $url = \'http://clientserver.com/getmyitems.php?cat=$cat\';
    $curl = curl_init();
    curl_setopt ($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    $items_json = curl_exec ($curl);
    curl_close ($curl);
    $items = json_decode($items_json);
    return $items->results;
}

function svod_get_items($svod_cat, $wp_cat) {
    global $processed_items;
    $new = 0;
    $update = 0;
    $items = svod_get_items_list($svod_cat);
    echo "Got items list with ".count($items)." items<br/>";
    flush();
    foreach ($items as $item) {
        if (($my_item = get_page_by_title( $item->VodTitle, OBJECT, \'svod_item\')) == NULL) {
            $id = svod_create_new_item($item, $wp_cat);
            $new++;
        } else {
            $id= svod_update_item($my_item, $item, $wp_cat);
            $update++;
        }
        $url = "http://example.com/import_item.php?item_id=$id";
        $curl = curl_init();
        curl_setopt ($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $res = curl_exec ($curl);
        curl_close ($curl);
        $processed_items[] = $id;
        echo $item->vodId . " ".$res."<br/>";
        flush();
    }
    echo "Done import; created $new, updated $update<br/>";
    flush();
}

function svod_create_new_item($item, $wp_cat) {
    $my_post = array(
          \'post_title\'    => $item->VodTitle,
          \'post_content\'  => \'\',
          \'post_status\'   => \'publish\',
          \'post_author\'   => 1,
          \'post_type\'     => \'svod_item\'
        );

    $pid = wp_insert_post($my_post);
    if (!is_wp_error($pid)) {
        wp_set_post_terms( $pid, array($wp_cat), \'svod_cat\', true);
        update_field(\'field_55ec1ed404c0e\', $item->VodId, $pid);
    }
    return $pid;
}

function svod_update_item($my_item, $item, $wp_cat) {
    wp_set_post_terms( $my_item->ID, array($wp_cat), \'svod_cat\', true);
    update_field(\'field_55ec1ed404c0e\', $item->VodId, $pid);
    return $my_item->ID;
}

$processed_items = array();

echo "Importing category ".$wp_cat.\'<br/>\';
$cat_id = get_field(\'cat_id\', \'svod_cat_\'.$wp_cat);
svod_get_items($cat_id, $wp_cat);

?>
脚本3:

    <?php 
/* Short and sweet */
define(\'WP_USE_THEMES\', false);
require(\'./wp-blog-header.php\');
set_time_limit(60);
error_reporting(E_ERROR | E_WARNING | E_PARSE);

function svod_get_item_info($vodid) {
    $url = \'https://clientserver.com/get_info.php?id=\'.$id;

    $curl = curl_init();
    curl_setopt ($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    $item_json = curl_exec ($curl);
    curl_close ($curl);
    $item = json_decode($item_json);
    return $item;
}

function svod_update_item($pid, $info) {

    $my_post = array(
      \'ID\'           => $pid,
      \'post_content\' => $info->VodDesc,
    );

    // Update the post into the database
    wp_update_post( $my_post );

    update_field(\'field_55ec08a2bc9bf\', $info->VodReleaseYear, $pid );
    update_field(\'field_55ec08a9bc9c0\', $info->VodRating, $pid);
    update_field(\'field_55ec08c4bc9c1\', $info->VodRunTime, $pid);
    update_field(\'field_55ec091bbc9c2\', $info->VodPosterUrl, $pid);
    update_field(\'field_55ec15f4bc9c3\', ($info->VodHD == \'true\'), $pid);
}

$wp_vod_id = $_GET[\'item_id\'];
$vod_id = get_field(\'vod_id\', $wp_vod_id);
$info = svod_get_item_info($vod_id);
svod_update_item($wp_vod_id, $info);
echo "<br/>Item updated !";
?>

3 个回复
SO网友:Dips Kakadiya

要避免超时,最佳选项是wp cli。Wp cli是wordpress命令行界面。您可以使用wp cli导出/导入数据。

SO网友:Marek

我会的split those operations into several actions. 如果不可能一次完成,就没有更好的解决方案了。主要问题是,如果错误是由客户端服务器超时(无法及时下载所有数据)或服务器超时(无法及时处理所有数据)引起的。另一个未知的问题是什么操作最耗时。脚本3?

我会创造一些custom DB tables. 然后运行cronjob下载所有类别并将它们保存到一个表中,然后运行另一个cronjob下载项目列表。然后是cronjob,每5分钟一次,例如列表中的10个项目,然后下载其“项目信息”。。。直到每个项目都有自己的信息。此时,您就拥有了来自客户机服务器的所有“源”数据。

之后,您可以运行另一个操作to process saved data 并将它们导入你的WP(可能不是全部成批,但再次拆分为更多次)。已处理的项目将从表中删除,当它为空时,导入完成。若某些运行失败/超时,则项目将保留在DB表中,并等待下次运行。不会有任何损失。

SO网友:Mark Kaplun

set_time_limit(0) 将禁用时间限制检查,如果这是实际问题,则应解决问题。您还可以尝试使用curl同时发送多个请求,这将使事情更快。

相关推荐