当同时发出许多API请求时,examplep崩溃


xampp crashes when many simultaneous API requests are made

我正在制作一个应用程序,该应用程序使用Twitter API接收用户的推文,其中一个组件是从推文文本中提取情感。为了进行开发,我使用了examplep,当然也使用ApacheHTMLServer作为我的工作区。我使用Eclipse for PHP作为IDE。

对于情感提取,我使用uClassify情感分类器。分类器使用API来接收大量请求,并随每个请求发送回XML数据,从中可以解析情感值。

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

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

EDIT:添加了有问题的源代码

更新索引方法

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;
}

问题是一次给curl提供了太多的URL。我很惊讶你能同时管理500个,因为我看到人们甚至抱怨200个有问题。这家伙有一些聪明的代码,每次只写100个,但每次完成后都会添加下一个,但我注意到他把它编辑成每次只写5个。

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

关于为什么会崩溃,关于这个问题的评论表明,原因可能是达到了操作系统文件句柄的最大数量:cURL连接的最大数量是多少?而其他建议只是简单地使用大量的带宽、CPU和内存。(如果您在windows上,打开任务管理器应该可以查看情况是否如此;在linux上使用top