加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

php – Laravel REST API和高CPU负载

发布时间:2020-12-14 19:41:28 所属栏目:大数据 来源:网络整理
导读:我正在使用Laravel 4开发一个简单的RESTful API. 我设置了一个Route,它调用我的Controller的功能,基本上这样做: 如果信息在数据库中,请将其打包成JSON对象并返回响应 否则尝试下载它(html / xml解析),存储它,最后打包JSON响应并发送它. 我注意到,CPU总共进
我正在使用Laravel 4开发一个简单的RESTful API.
我设置了一个Route,它调用我的Controller的功能,基本上这样做:

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

我注意到,CPU总共进行了1700次请求,一次只有2次,提高到70-90%.

我是一个完整的php和laravel初学者,我已经使API跟随this tutorial,也许我可能在做错了,或者只是一个概念缺乏最佳化的证明.我如何改进这个代码? (启动函数是getGames)
你认为所有问题的根源是Laravel还是应该获得相同的结果甚至改变框架/使用原始的PHP?

UPDATE1我还设置了一个文件Cache,但CPU负载仍然是?50%.

UPDATE2我将查询速率设置为每500ms两次,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

UPDATE举个例子,我不得不重新考虑你的代码(而且我很懒惰,因为任何东西!).但是,我可以肯定地告诉你:如果你把你的请求代码,那些打电话给他人的站点的XML,到队列你将获得大量的空闲CPU时间.每个请求被重定向到一个队列.一旦他们准备好了,你会按照你的意愿对待他们. Laravel有一个美丽的方式来处理队列.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读