服务器在重负载下不断崩溃(facebook SDK + Laravel 5.2 + AWS)
Server keeps crashing on heavy load (facebook SDK + Laravel 5.2 + AWS)
我在 AWS 的免费套餐上,使用 laravel 框架和 facebook v.2.5 SDK (Web)。我正在尝试从 facebook 获取大约 600 个用户的最新 10 个帖子。最多 6000 个帖子。每次我 运行 查询时,它都会 运行 循环大约 10 次,然后应用程序完全崩溃并离线。然后 returns 几分钟后。 Laravel 没有向我显示任何错误。
我的代码是:
/**
* Get facebook users posts
* @return \SammyK\LaravelFacebookSdk\LaravelFacebookSdk;
*/
public function posts(\SammyK\LaravelFacebookSdk\LaravelFacebookSdk $fb)
{
// get posts
$profiles_to_get = DB::table('facebook_profiles')->distinct('username')->get();
$fb_admin_profile = DB::table('profiles')->where('social_media_type', "facebook")->first();
$admin_fb_access_token = $fb_admin_profile->oauth_token;
foreach ($profiles_to_get as $profile_to_get) {
try {
$response = $fb->get('/'.$profile_to_get->username.'?fields=posts.limit(10)', $admin_fb_access_token);
$userNode = $response->getGraphUser();
$posts = json_decode($userNode['posts']);
foreach ($posts as $post)
{
isset($post->message) ? $fb_posts[] = array('account_id' => $profile_to_get->id,
'facebook_id' => $userNode->getID(),
'message_id' => $post->id,
'message' => $post->message,
'created_time' => $post->created_time->date,
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
) : null;
foreach ($fb_posts as $fb_post)
{
$postDuplicateChecker = DB::table('facebook_posts')->where('message_id', $fb_post['message_id'])->get();
if($postDuplicateChecker == !null)
{
DB::table('facebook_posts')->where('message_id', $fb_post['message_id'])->update($fb_post);
$notification = "First notification";
}
else
{
DB::table('facebook_posts')->insert( $fb_post );
$notification = "Second notification";
}
}
if ($post > 0 && $post % 10 == 0)
{
sleep(5);
}
}
} catch(\Facebook\Exceptions\FacebookSDKException $e) {
dd($e->getMessage());
}
}
return Redirect::route('someroute',[ 'notification' => $notification]);
}
我试过将查询超时设置为 300,这样它就不会超时,并且在每 10 个请求后让循环休眠,以减少负载。我还有其他应用程序 运行ning 在同一台服务器上,但当此应用程序崩溃时它们永远不会离线。
我的问题是有没有什么方法可以优化代码,这样我就不必升级服务器,或者是我升级服务器的唯一选择?
答案是使用 array_chunk 对查询进行批处理,并将过程分成更小的部分,以便更容易处理。
array array_chunk ( array $array , int $size [, bool $preserve_keys = false ] )
我在 AWS 的免费套餐上,使用 laravel 框架和 facebook v.2.5 SDK (Web)。我正在尝试从 facebook 获取大约 600 个用户的最新 10 个帖子。最多 6000 个帖子。每次我 运行 查询时,它都会 运行 循环大约 10 次,然后应用程序完全崩溃并离线。然后 returns 几分钟后。 Laravel 没有向我显示任何错误。
我的代码是:
/**
* Get facebook users posts
* @return \SammyK\LaravelFacebookSdk\LaravelFacebookSdk;
*/
public function posts(\SammyK\LaravelFacebookSdk\LaravelFacebookSdk $fb)
{
// get posts
$profiles_to_get = DB::table('facebook_profiles')->distinct('username')->get();
$fb_admin_profile = DB::table('profiles')->where('social_media_type', "facebook")->first();
$admin_fb_access_token = $fb_admin_profile->oauth_token;
foreach ($profiles_to_get as $profile_to_get) {
try {
$response = $fb->get('/'.$profile_to_get->username.'?fields=posts.limit(10)', $admin_fb_access_token);
$userNode = $response->getGraphUser();
$posts = json_decode($userNode['posts']);
foreach ($posts as $post)
{
isset($post->message) ? $fb_posts[] = array('account_id' => $profile_to_get->id,
'facebook_id' => $userNode->getID(),
'message_id' => $post->id,
'message' => $post->message,
'created_time' => $post->created_time->date,
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
) : null;
foreach ($fb_posts as $fb_post)
{
$postDuplicateChecker = DB::table('facebook_posts')->where('message_id', $fb_post['message_id'])->get();
if($postDuplicateChecker == !null)
{
DB::table('facebook_posts')->where('message_id', $fb_post['message_id'])->update($fb_post);
$notification = "First notification";
}
else
{
DB::table('facebook_posts')->insert( $fb_post );
$notification = "Second notification";
}
}
if ($post > 0 && $post % 10 == 0)
{
sleep(5);
}
}
} catch(\Facebook\Exceptions\FacebookSDKException $e) {
dd($e->getMessage());
}
}
return Redirect::route('someroute',[ 'notification' => $notification]);
}
我试过将查询超时设置为 300,这样它就不会超时,并且在每 10 个请求后让循环休眠,以减少负载。我还有其他应用程序 运行ning 在同一台服务器上,但当此应用程序崩溃时它们永远不会离线。
我的问题是有没有什么方法可以优化代码,这样我就不必升级服务器,或者是我升级服务器的唯一选择?
答案是使用 array_chunk 对查询进行批处理,并将过程分成更小的部分,以便更容易处理。
array array_chunk ( array $array , int $size [, bool $preserve_keys = false ] )