Рубрики
Uncategorized

Практика одновременного вызова сопрограммы Swool-решение проблемы блокировки последовательного ввода-вывода

Автор оригинала: David Wong.

Предисловие

В рамках традиционной архитектуры PHP SNMP нас всегда беспокоили некоторые проблемы. Поскольку PHP-программы могут выполняться только последовательно, в приложениях с интенсивным вводом-выводом PHP-программы могут выполнять следующий код только после завершения операции ввода-вывода, большинство из которых ожидают ввода-вывода, что серьезно влияет на эффективность выполнения. Это очень неразумно. Теперь существует сценарий, в котором интерфейсу необходимо вызвать 10 сторонних HTTP-интерфейсов, чтобы получить все данные. Предполагая, что каждый вызов интерфейса занимает в среднем 300 мс, для завершения в традиционном последовательном режиме PHP требуется 3 секунды. Эта проблема может быть решена с помощью протокола Httpclient на основе Вулфа для реализации одновременного вызова Http-запросов.

практика

Давайте использовать следующий Традиционный HttpClient и Клиент совместной работы Swool Сравнивая общее время отклика запросов, преимущества одновременного вызова можно интуитивно увидеть с помощью N последовательных запросов на домашнюю страницу Taobao.

Пример традиционного Http-клиента

$start = microtime(true);
$n = 50;
for ($i = 0; $i < $n; $i++) {
    $http = new Http();
    $res = $http->get('https://www.taobao.com/');
    $res->getBody()->getContents();
}
$end = microtime(true);
echo bcsub($end,$start,2).PHP_EOL;

Пример Http-Клиента Swool Для Совместной Обработки

go(function (){
    $start = microtime(true);
    // Concurrent request n
    $result = [];
    $clients = [];
    $n = 50;
    for ($i = 0; $i < $n; $i++) {
        $cli = new \Swoole\Coroutine\Http\Client('www.taobao.com', 443,true);
        $cli->setHeaders([
            'Host' => "www.taobao.com",
            "User-Agent" => 'Chrome/49.0.2587.3',
            'Accept' => 'text/html,application/xhtml+xml,application/xml',
            'Accept-Encoding' => 'gzip',
        ]);
        $cli->set(['timeout' => 2]);
        $cli->setDefer();
        $cli->get('/');
        $clients[] = $cli;
    }

    for ($i = 0; $i < $n; $i++) {
        if (!$clients[$i]->recv()) {
            continue;
        }

        $result[] = $clients[$i]->body;
    }

    $end = microtime(true);
    echo bcsub($end,$start,2).PHP_EOL;
});

Анализ данных

10 Анализ данных Анализ данных
20 Анализ данных Анализ данных
30 Анализ данных Анализ данных
50 Анализ данных Анализ данных
100 Анализ данных Анализ данных

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

Графика последовательных и одновременных вызовов

резюме

Если вы, как и я, в сценарии с интенсивным вводом-выводом скорость программы достигла узкого места, независимо от того, насколько оптимизирована, скорость не была улучшена качественно, тогда вы можете попробовать режим протокола Swool, который может принести неожиданные результаты. В большинстве веб-сценариев дело не в том, что наша программа выполняется медленно, а в том, что большую часть времени мы ждем окончания ввода-вывода. Независимо от того, как оптимизировать код, улучшение не очевидно. Лучше изменить образ мышления и решить проблему асинхронного ожидания ввода-вывода с помощью совместной работы. Улучшение огромно. Я надеюсь, что эта статья поможет вам!