【问题标题】:xampp crashes when many simultaneous API requests are made当同时发出许多 API 请求时,xampp 崩溃
【发布时间】:2015-02-08 22:01:20
【问题描述】:

我正在制作一个应用程序,它使用 Twitter API 接收用户的推文,其中一个组件是从推文文本中提取情绪。对于开发,我使用 xampp,当然使用 Apache HTML Server 作为我的工作区。我正在使用 Eclipse for PHP 作为 IDE。

对于情感提取,我使用的是uClassify Sentiment Classifier。分类器使用 API 接收大量请求,并针对每个请求发回可解析情绪值的 XML 数据。

现在应用程序可以一次处理大量推文(最多允许 3200 条)。例如,如果有 3200 条推文,那么系统将一次向该分类器发送 3200 个 API 调用。不幸的是,对于这个数字,系统无法很好地扩展,实际上 xampp 在使用这些调用运行系统后不久就会崩溃。但是,对于少量的推文(例如 500 条推文),系统运行良好,所以我假设这可能是由于大量 API 调用造成的。请注意,uClassify 每天允许的 API 调用的最大数量为 5000,但由于最大值为 3200,我很确定它不会超过这个数字。

这几乎是我第一次从事这种网络开发工作,所以我不确定我是否在这里犯了一个新手错误。我不确定我可能做错了什么,也不知道从哪里开始寻找。任何建议/见解都会有很大帮助!

编辑:添加有问题的源代码

更新索引方法

function updateIndex($timeline, $connection, $user_handle, $json_index, $most_recent) {
    // URL arrays for uClassify API calls
    $urls = [ ];
    $urls_id = [ ];

    // halt if no more new tweets are found
    $halt = false;
    // set to 1 to skip first tweet after 1st batch
    $j = 0;
    // count number of new tweets indexed
    $count = 0;
    while ( (count ( $timeline ) != 1 || $j == 0) && $halt == false ) {
        $no_of_tweets_in_batch = 0;
        $n = $j;
        while ( ($n < count ( $timeline )) && $halt == false ) {
            $tweet_id = $timeline [$n]->id_str;
            if ($tweet_id > $most_recent) {
                $text = $timeline [$n]->text;
                $tokens = parseTweet ( $text );
                $coord = extractLocation ( $timeline, $n );
                addSentimentURL ( $text, $tweet_id, $urls, $urls_id );
                $keywords = makeEntry ( $tokens, $tweet_id, $coord, $text );
                foreach ( $keywords as $type ) {
                    $json_index [] = $type;
                }
                $n ++;
                $no_of_tweets_in_batch ++;
            } else {
                $halt = true;
            }
        }
        if ($halt == false) {
            $tweet_id = $timeline [$n - 1]->id_str;

            $timeline = $connection->get ( 'statuses/user_timeline', array (
                    'screen_name' => $user_handle,
                    'count' => 200,
                    'max_id' => $tweet_id 
            ) );
            // skip 1st tweet after 1st batch
            $j = 1;
        }
        $count += $no_of_tweets_in_batch;
    }

    $json_index = extractSentiments ( $urls, $urls_id, $json_index );

    echo 'Number of tweets indexed: ' . ($count);
    return $json_index;
}

情感提取法

function extractSentiments($urls, $urls_id, &$json_index) {
    $responses = multiHandle ( $urls );
    // add sentiments to all index entries
    foreach ( $json_index as $i => $term ) {
        $tweet_id = $term ['tweet_id'];
        foreach ( $urls_id as $j => $id ) {
            if ($tweet_id == $id) {
                $sentiment = parseSentiment ( $responses [$j] );
                $json_index [$i] ['sentiment'] = $sentiment;
            }
        }
    }
    return $json_index;
}

处理多个 API 调用的方法

这是一次处理 uClassify API 调用的地方:

function multiHandle($urls) {

    // curl handles
    $curls = array ();

    // results returned in xml
    $xml = array ();

    // init multi handle
    $mh = curl_multi_init ();

    foreach ( $urls as $i => $d ) {
        // init curl handle
        $curls [$i] = curl_init ();

        $url = (is_array ( $d ) && ! empty ( $d ['url'] )) ? $d ['url'] : $d;

        // set url to curl handle
        curl_setopt ( $curls [$i], CURLOPT_URL, $url );

        // on success, return actual result rather than true
        curl_setopt ( $curls [$i], CURLOPT_RETURNTRANSFER, 1 );

        // add curl handle to multi handle
        curl_multi_add_handle ( $mh, $curls [$i] );
    }

    // execute the handles
    $active = null;
    do {
        curl_multi_exec ( $mh, $active );
    } while ( $active > 0 );

    // get xml and flush handles
    foreach ( $curls as $i => $ch ) {
        $xml [$i] = curl_multi_getcontent ( $ch );
        curl_multi_remove_handle ( $mh, $ch );
    }

    // close multi handle
    curl_multi_close ( $mh );

    return $xml;
}

【问题讨论】:

  • 您会收到一个 http 请求进入您的 xampp Web 服务器,即用户名,然后在 PHP 中查找他们的推文,然后仍然在同一个 PHP 脚本中循环浏览这些推文,进行一次调用到每个外部网络服务(uClassify)?如果是这样,发布您的 PHP 脚本可能会很有用(或者,如果它很长,则发布主循环 - 我对您如何执行 Web 服务调用以及如何并行执行它们特别感兴趣。)
  • 我正在使用 cURL 来调用 uClassify。我不是每次都为每条推文处理一个调用,而是将一个 curl 句柄添加到一个多句柄(仍在 cURL 中),然后使用 multi_exec()(对于 curl 多句柄)并行处理它们,或者说根据到 libcurl 文档。这使得处理所有这些推文的过程快得多,但它不能很好地扩展到大量推文。我只用大约 300-500 条推文成功地测试了它,它不能在 3200 条推文上正常工作。我已经用代码编辑了帖子。

标签: php api twitter sentiment-analysis


【解决方案1】:

问题在于一次性给 curl 太多 URL。我很惊讶你可以并行管理 500 个,因为我看到人们抱怨甚至 200 个问题。This guy has some clever code 一次只有 100 个,但是每次完成时添加下一个,但我注意到他编辑了它一次只做 5 个。

我刚刚注意到该代码的作者围绕这个想法发布了一个开源库,所以我认为这是适合你的解决方案:https://github.com/joshfraser/rolling-curl

至于为什么会崩溃,对此问题的评论表明原因可能是达到了 OS 文件句柄的最大数量:What is the maximum number of cURL connections set by? 和其他建议只是使用大量带宽、CPU 和内存。 (如果你在windows上,打开任务管理器应该可以让你看看是否是这种情况;在linux上使用top

【讨论】:

  • 哇,这真的很有帮助,我一定会查看链接!我将再次在这里发帖,看看我是否可以解决这个问题。谢谢!
猜你喜欢
  • 2020-12-27
  • 1970-01-01
  • 1970-01-01
  • 2021-03-23
  • 1970-01-01
  • 1970-01-01
  • 2017-05-03
  • 2016-04-23
  • 2015-08-26
相关资源
最近更新 更多