График Facebook чрезвычайно медленный в PHP


Независимо от того, используете ли вы PHP SDK Facebook или просто загружаете данные с помощью curl с помощью $contents = file_get_contents("https://graph.facebook.com/$id?access_token=$accessToken"), для получения ответа требуется около целой секунды.

Это считается очень медленным, когда мне нужно проверить данные на наличие нескольких идентификаторов.

Когда в браузере я набираю URL-адрес графика facebook, я получаю результаты почти мгновенно, менее чем за десятую часть времени, которое требуется в PHP.

В чем причина этой проблемы и как я могу сделать это так быстро, как это было бы в любом браузере? Я знаю, что браузер может это сделать. В PHP тоже должен быть способ сделать это быстро.

ИДЕЯ: возможно, мне нужно что-то настроить в cURL?

Что я пробовал:

  • С использованием PHP SDK. Это так же медленно. Причина, по которой я попытался использовать file_get_contents() в первую очередь, заключалась в том, что я надеялся, что PHP SDK не был настроен должным образом.
  • Используя setopt($ch, CURLOPT_SSL_VERIFYPEER, false);. Это не имело никакого значения. ПОСЛЕ ОТВЕТА ПРИМИТЕ РЕДАКТИРОВАНИЕ: на самом деле, это вместе с повторным использованием ручки завитка сделало последующие запросы действительно быстро.

РЕДАКТИРОВАТЬ: вот фрагмент кода, который я использовал для измерения времени, необходимого для выполнения запросов: http://pastebin.com/bEbuqq5g . Я исправил текст, в котором раньше говорилось о микросекундах, на секунды. это то, что дает результаты, аналогичные тем, которые я написал в своем комментарии к этому вопросу: График Facebook чрезвычайно медленный в PHP. Обратите также внимание, что они работают одинаково медленно, даже если срок действия маркера доступа истек, как в моем примере с pastebin.

ПРАВКА 2: там частично это должно быть проблемой с ssl. Я попробовал провести сравнительный анализ http://graph.facebook.com/4 (без httpS), и это заняло 1,2 секунды для трех запросов, тогда как то же самое, но с https заняло 2,2 секунды. Однако это никоим образом не решение, потому что для любого запроса, которому требуется маркер доступа, я должен использовать https.

Author: Community, 2012-07-10

5 answers

Я задавался вопросом, что произойдет, если я сделаю два последующих вызова curl_exec() без выполнения curl_close(), что позволит использовать HTTP Keep-Alive.

Тестовый код:

$ch = curl_init('https://graph.facebook.com/xxx');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

// FIRST REQUEST
curl_exec($ch);
print_r(curl_getinfo($ch));

// SECOND REQUEST
curl_exec($ch);
print_r(curl_getinfo($ch));

curl_close($ch);

Ниже приведены результаты, показывающие части выходных данных из curl_getinfo():

// FIRST REQUEST
[total_time] => 0.976259
[namelookup_time] => 0.008271
[connect_time] => 0.208543
[pretransfer_time] => 0.715296

// SECOND REQUEST
[total_time] => 0.253083
[namelookup_time] => 3.7E-5
[connect_time] => 3.7E-5
[pretransfer_time] => 3.9E-5

Первый запрос выполняется довольно медленно, почти целую секунду, аналогично вашему опыту. Но со времени второго запроса (всего 0,25 секунды) вы можете видеть, насколько сильно изменилось сохранение жизни.

Ваш браузер использует этот метод, а также, конечно, загрузка страницы в новом экземпляре вашего браузера заняли бы значительно больше времени.

 7
Author: Ja͢ck, 2012-08-29 06:47:28

file_get_contents может быть очень медленным в PHP, потому что он неправильно отправляет/обрабатывает заголовки, что приводит к неправильному закрытию HTTP-соединения после завершения передачи файлов. Я также читал о проблемах с DNS, хотя у меня нет никакой информации об этом.

Решение, которое я настоятельно рекомендую, состоит в том, чтобы либо использовать PHP SDK, который предназначен для выполнения вызовов API в Facebook, либо использовать CURL (который использует SDK). С помощью cURL вы действительно можете настроить множество аспекты запроса, так как он в основном предназначен для выполнения подобных вызовов API.

Информация о PHP SDK: https://developers.facebook.com/docs/reference/php/

Источник PHP SDK: https://github.com/facebook/facebook-php-sdk

Если вы решите сделать это без SDK, вы можете посмотреть, как они используют cURL в base_facebook.php . вот пример кода, который вы могли бы использовать для извлечения с помощью cURL:

function get_url($url)
{
   $ch = curl_init();
   curl_setopt($ch, CURLOPT_URL, $url); 
   curl_setopt($ch, CURLOPT_HEADER, FALSE);  // Return contents only
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);  // return results instead of outputting
   curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10) // Give up after connecting for 10 seconds 
   curl_setopt($ch, CURLOPT_TIMEOUT, 60);  // Only execute 60s at most
   curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);  // Don't verify SSL cert
   $response = curl_exec($ch);
   curl_close($ch);
   return $response;
}

$contents = get_url("https://graph.facebook.com/$id?access_token=$accessToken");

Функция вернет ЛОЖЬ при неудаче.

Я вижу, что вы сказали, что использовали PHP SDK, но, возможно, у вас не был настроен cURL. Попробуйте установить или обновить , и если он все еще кажется медленным, вам следует использовать

curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_VERBOSE, TRUE);

И проверьте результат.

 8
Author: AndrewF, 2012-08-22 12:55:15

Всего две мысли:

  1. Вы убедились, что браузер не имеет постоянного подключения к facebook? Что браузер не кэшировал поиск DNS (вы можете попробовать добавить graph.facebook.net на ваши хосты-файл для управления DNS-входом/выходом)

  2. Вы, конечно, запускаете php-код из той же системы/среды, что и ваш браузер (не с виртуальной машины, не с другого хоста? Также, что php работает с теми же приоритетами планирования, что и ваш браузер? (такой же приятный уровень и т. д))

 2
Author: Eirik S, 2012-08-28 17:00:50

В целом самым большим фактором, делающим вызовы Graph API "медленными", является HTTP-соединение.

Возможно, там есть небольшое улучшение, путем настройки некоторых параметров или получения сервера с лучшим подключением.

Но это, скорее всего, не будет иметь большой разницы, поскольку HTTP обычно считается "медленным", и с этим мало что можно сделать.

Это считается очень медленным, когда мне нужно проверить данные на наличие удостоверения личности.

Лучшее, что вы можете сделать, чтобы ускорить процесс, это, конечно, – свести к минимуму количество HTTP-запросов.

Если вам нужно выполнить несколько вызовов API Graph подряд, попробуйте вместо этого выполнить их в виде пакетного запроса . Это позволяет вам запрашивать несколько частей данных, в то же время делая только один HTTP-запрос.

 1
Author: CBroe, 2012-08-23 15:45:24

Это чисто предположение, однако причиной может быть то, что Facebook использует протокол SPDY (не уверен, верно ли это для API). PHP не может загрузить страницу с помощью протокола SPDY.

 0
Author: Henrik Karlsson, 2012-08-29 08:46:50