Очень долгая загрузка php curl - PullRequest
0 голосов
/ 27 апреля 2018

Я пытаюсь создать сайт для моего клана на поле боя 1, на одной из страниц которого я хотел бы показать нашу команду и некоторые их характеристики.

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

Вот мой код

<?php
$data = $connection->query("SELECT * FROM bfplayers");
while($row = mysqli_fetch_assoc($data)){
$psnid = $row['psnid'];


$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://battlefieldtracker.com/bf1/api/Stats/BasicStats?platform=2&displayName=".$psnid);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

$headers = [
    'TRN-Api-Key: MYKEY',
];

curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);

print($result['profile']['displayName']);
    }
?>

Я понятия не имею, почему это происходит так медленно, потому что я использую xamp на локальном хосте или потому что запросы проходят через цикл?

Заранее спасибо

1 Ответ

0 голосов
/ 27 апреля 2018

ваш цикл не оптимизирован ни в малейшей степени, я полагаю, что если вы оптимизировали свой код цикла, ваш код мог бы работать ОЧЕНЬ быстрее. вы создаете и удаляете дескриптор скручивания на каждой итерации, когда вы можете просто продолжать использовать один и тот же дескриптор скручивания на каждом проигрывателе (это будет использовать меньше ресурсов процессора и будет быстрее), вы не используете сжатую передачу (включение сжатия, вероятно, приведет к передача быстрее), и что наиболее важно, вы выполняете вызовы API последовательно, я полагаю, что если вы выполняете запросы API параллельно, он будет загружаться гораздо быстрее. Кроме того, вы не urlencode PSNID, это, вероятно, ошибка. попробуйте это

<?php
$cmh = curl_multi_init ();
$curls = array ();
$data = $connection->query ( "SELECT * FROM bfplayers" );

while ( ($row = mysqli_fetch_assoc ( $data )) ) {
    $psnid = $row ['psnid'];
    $tmp = array ();
    $tmp [0] = ($ch = curl_init ());
    $tmp [1] = tmpfile ();
    $curls [] = $tmp;
    curl_setopt_array ( $ch, array (
            CURLOPT_URL => "https://battlefieldtracker.com/bf1/api/Stats/BasicStats?platform=2&displayName=" . urlencode ( $psnid ),
            CURLOPT_ENCODING => '',
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_HTTPHEADER => array (
                    'TRN-Api-Key: MYKEY' 
            ),
            CURLOPT_FILE => $tmp [1] 
    ) );
    curl_multi_add_handle ( $cmh, $ch );
    curl_multi_exec ( $cmh, $active );
}
do {
    do {
        $ret = curl_multi_exec ( $cmh, $active );
    } while ( $ret == CURLM_CALL_MULTI_PERFORM );
    curl_multi_select ( $cmh, 1 );
} while ( $active );
foreach ( $curls as $curr ) {
    fseek ( $curr [1], 0, SEEK_SET ); // https://bugs.php.net/bug.php?id=76268
    $response = stream_get_contents ( $curr [1] );
    $result = json_decode ( $response,true );
    print ($result ['profile'] ['displayName']) ;
}
// the rest is just cleanup, the client shouldn't have to wait for this
// OPTIMIZEME: apache version of fastcgi_finish_request() ?
if (is_callable ( 'fastcgi_finish_request' )) {
    fastcgi_finish_request ();
}
foreach ( $curls as $curr ) {
    curl_multi_remove_handle ( $cmh, $curr [0] );
    curl_close ( $curr [0] );
    fclose ( $curr [1] );
}
curl_multi_close ( $cmh );
  • он выполняет все вызовы API параллельно и использует сжатие передачи (CURLOPT_ENCODING), параллельно запускает запросы API с загрузкой результатов из базы данных, и он пытается отключить клиент перед запуском процедур очистки, он, вероятно, будет работать намного быстрее ,

также, если mysqli_fetch_assoc () вызывает медленные обращения к вашей базе данных, вероятно, было бы еще быстрее заменить ее на mysqli_fetch_all ()

Кроме того, что-то, что, вероятно, будет гораздо быстрее, чем это, - это запускать cronjob каждую минуту (или каждые 10 секунд?), Который кэширует результаты и показывает кэшированный результат клиенту. (даже если API вызывает лаги, загрузка страницы клиента не будет затронута вообще.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...