gpt4 book ai didi

php - Laravel REST API 和高 CPU 负载

转载 作者:IT王子 更新时间:2023-10-28 23:49:57 25 4
gpt4 key购买 nike

我正在使用 Laravel 4 开发一个简单的 RESTful API。我设置了一个 Route 来调用我的 Controller 的函数,该函数基本上是这样做的:

  • 如果信息在数据库中,则将其打包到 JSON 对象中并返回响应
  • 否则尝试下载它(html/xml 解析),存储它,最后打包 JSON 响应并发送它。

我注意到,在总共执行 1700 个请求(一次只有 2 个请求)时,CPU 负载上升到 70-90%。

我是一个完整的 php 和 laravel 初学者,我已经按照 this tutorial 创建了 API ,也许我可能做错了什么,或者这只是缺乏优化的概念证明。如何改进此代码? (启动函数是getGames)你认为所有问题的根源是 Laravel 还是我应该得到相同的结果,即使改变框架/使用原始 PHP?

UPDATE1我也设置了一个文件缓存,但是CPU负载还是~50%。

UPDATE2 我将查询速率设置为每 500 毫秒两次,CPU 负载降低了 12%,所以我猜这段代码缺少队列处理或类似的东西。

class GameController extends BaseController{
private static $platforms=array(
"Atari 2600",
"Commodore 64",
"Sega Dreamcast",
"Sega Game Gear",
"Nintendo Game Boy",
"Nintendo Game Boy Color",
"Nintendo Game Boy Advance",
"Atari Lynx",
"M.A.M.E.",
"Sega Mega Drive",
"Colecovision",
"Nintendo 64",
"Nintendo DS",
"Nintendo Entertainment System (NES)",
"Neo Geo Pocket",
"Turbografx 16",
"Sony PSP",
"Sony PlayStation",
"Sega Master System",
"Super Nintendo (SNES)",
"Nintendo Virtualboy",
"Wonderswan");
private function getDataTGDB($name,$platform){
$url = 'http://thegamesdb.net/api/GetGame.php?';
if(null==$name || null==$platform) return NULL;
$url.='name='.urlencode($name);
$xml = simplexml_load_file($url);
$data=new Data;
$data->query=$name;
$resultPlatform = (string)$xml->Game->Platform;

$data->platform=$platform;
$data->save();
foreach($xml->Game as $entry){
$games = Game::where('gameid',(string)$entry->id)->get();
if($games->count()==0){
if(strcasecmp($platform , $entry->Platform)==0 ||
(strcasecmp($platform ,"Sega Mega Drive")==0 &&
($entry->Platform=="Sega Genesis" ||
$entry->Platform=="Sega 32X" ||
$entry->Platform=="Sega CD"))){
$game = new Game;
$game->gameid = (string)$entry->id;
$game->title = (string)$entry->GameTitle;
$game->releasedate = (string)$entry->ReleaseDate;
$genres='';
if(NULL!=$entry->Genres->genre)
foreach($entry->Genres->genre as $genre){
$genres.=$genre.',';
}
$game->genres=$genres;
unset($genres);
$game->description = (string)$entry->Overview;
foreach($entry->Images->boxart as $boxart){
if($boxart["side"]=="front"){
$game->bigcoverurl = (string)$boxart;
$game->coverurl = (string) $boxart["thumb"];
} continue;
}
$game->save();
$data->games()->attach($game->id);
}
}
else foreach($games as $game){
$data->games()->attach($game->id);
}
}
unset($xml);
unset($url);
return $this->printJsonArray($data);
}

private function getArcadeHits($name){
$url = "http://www.arcadehits.net/index.php?p=roms&jeu=";
$url .=urlencode($name);

$html = file_get_html($url);

$data = new Data;
$data->query=$name;
$data->platform='M.A.M.E.';
$data->save();
$games = Game::where('title',$name)->get();
if($games->count()==0){
$game=new Game;
$game->gameid = -1;
$title = $html->find('h4',0)->plaintext;
if("Derniers jeux commentés"==$title)
{
unset($game);
return Response::json(array('status'=>'404'),200);
}
else{
$game->title=$title;
$game->description="(No description.)";
$game->releasedate=$html->find('a[href*=yearz]',0)->plaintext;
$game->genres = $html->find('a[href*=genre]',0)->plaintext;
$minithumb = $html->find('img.minithumb',0);
$game->coverurl = $minithumb->src;
$game->bigcoverurl = str_replace("/thumb/","/jpeg/",$minithumb->src);
$game->save();
$data->games()->attach($game->id);
}
}

unset($html);
unset($url);
return $this->printJsonArray($data);
}

private function printJsonArray($data){
$games = $data->games()->get();
$array_games = array();
foreach($games as $game){
$array_games[]=array(
'GameTitle'=>$game->title,
'ReleaseDate'=>$game->releasedate,
'Genres'=>$game->genres,
'Overview'=>$game->description,
'CoverURL'=>$game->coverurl,
'BigCoverURL'=>$game->bigcoverurl
);
}
$result = Response::json(array(
'status'=>'200',
'Game'=>$array_games
),200);
$key = $data->query.$data->platform;
if(!Cache::has($key))
Cache::put($key,$result,1440);
return $result;
}

private static $baseImgUrl = "";
public function getGames($apikey,$title,$platform){
$key = $title.$platform;
if(Cache::has($key)) return Cache::get($key);
if(!in_array($platform,GameController::$platforms)) return Response::json(array("status"=>"403","message"=>"non valid platform"));
$datas = Data::where('query',$title)
->where('platform',$platform)
->get();
//If this query has already been done we return data,otherwise according to $platform
//we call the proper parser.
if($datas->count()==0){
if("M.A.M.E."==$platform){
return $this->getArcadeHits($title);
}
else{
return $this->getDataTGDB($title,$platform);
}
} else{
else return $this->printJsonArray($datas->first());
}
}


}
?>

最佳答案

您正在尝试从其他人的服务器检索数据。那就是让你的 CPU “暂停”,直到数据被完全检索。这就是使您的代码如此“CPU 昂贵”的原因 (找不到适合这里的其他东西 =/),因为您的脚本正在等待直到收到数据然后释放脚本(CPU)工作。

强烈建议您进行异步调用。这将释放您的 CPU 来处理代码,而您系统的其他部分正在获取您需要的信息。

希望对您有所帮助! =D

更新
为了举例说明,我必须重构您的代码(而且我很懒惰!)。但是,我可以肯定地告诉你:如果你把你的请求代码,那些调用其他站点的 XML 的代码,放到一个队列中,你将获得大量的空闲 CPU 时间。每个请求都被重定向到一个队列。一旦他们准备好了,你就可以随心所欲地对待他们。 Laravel 有一种处理队列的漂亮方法。

关于php - Laravel REST API 和高 CPU 负载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21816682/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com