我正在制作一个应用程序,它使用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;
}
答案 0 :(得分:1)
问题在于一次性为curl提供过多的URL。我很惊讶你可以同时管理500个,因为我已经看到人们抱怨甚至200个问题。This guy has some clever code一次只有100个,但是每次完成后添加下一个,但是我注意他把它编辑成一次只做5次。
我刚刚注意到该代码的作者围绕这个想法发布了一个开源库,所以我认为这是适合您的解决方案:https://github.com/joshfraser/rolling-curl
至于你为什么会崩溃,对这个问题的评论表明原因可能是达到操作系统文件句柄的最大数量:What is the maximum number of cURL connections set by?而其他建议只是使用了大量的带宽,CPU和内存。 (如果您在Windows上,打开任务管理器应该允许您查看是否是这种情况;在Linux上使用top
)