PHP асинхронность, многопоточность, параллельность

1 23
T7
На сайте с 19.09.2018
Offline
63
#21
Dreammaker #:
Подскажите, что какую мысль вы хотите донести,  суммируя время доставки двух страниц?

Для расширения кругозора, хотел пример кода с использованием какой то асинхронной библиотеки на пхп,  когда скрипт, выполняя 2 задачи, отрабатывает за x сек, тогда как время затраченное на 2 документов составило 2х.

Вероятно, на базе этого: https://www.php.net/manual/ru/intro.parallel.php , что то типа аиохттп у питона. Чтобы в несколько строк, реализовать какой то асинхронный парсер например.

PHP: Введение - Manual
  • www.php.net
parallel - это модуль параллельного выполнения для PHP ≥ 7.2.0. Начиная с parallel 1.2.0, требуется PHP ≥ 8.0.0. Краткое описание основных понятий параллельных процессов описано ниже, более подробную информацию можно найти в этом разделе руководства. Runtime представляет поток интерпретатора PHP. настроен с дополнительным файлом начальной...
Dreammaker
На сайте с 20.04.2006
Offline
570
#22
timo-71 #:
Для расширения кругозора, хотел пример кода с использованием какой то асинхронной библиотеки на пхп,  когда скрипт, выполняя 2 задачи, отрабатывает за x сек, тогда как время затраченное на 2 документов составило 2х.
<?php 

require_once('../protected/vendor/autoload.php');

use GuzzleHttp\Client;
use GuzzleHttp\Promise\PromiseInterface;

$client = new Client();

$timing = [];

$function = function (PromiseInterface $promise) use (&$timing) {
    $startTime = microtime(true);

    return $promise->then(function ($response) use ($startTime, &$timing) {
        $dom = new DOMDocument();
        
        libxml_use_internal_errors(true);
        $dom->loadHTML((string) $response->getBody() , LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
        libxml_clear_errors();
        
        $title = $dom->getElementsByTagName('title')->item(0)->nodeValue;

        $endTime = microtime(true);
        $timing[] = $endTime - $startTime;

        echo "Request time: " . ($endTime - $startTime) . PHP_EOL, $title . PHP_EOL;
    });
};

$startTime = microtime(true);

$promises = [
    $function($client->getAsync('1074587')),
    $function($client->getAsync('1074587')),
];

GuzzleHttp\Promise\all($promises)->wait();

echo "Вместе: " . (microtime(true) - $startTime) . PHP_EOL;

echo "сумма раздельно: " . array_sum($timing) . PHP_EOL;
Request time: 0.25532793998718
PHP асинхронность, многопоточность, параллельность - Веб-строительство - Сайтостроение - Форум об интернет-маркетинге
Request time: 0.26136803627014
PHP асинхронность, многопоточность, параллельность - Веб-строительство - Сайтостроение - Форум об интернет-маркетинге
Вместе: 0.26281094551086
Total time: 0.51669597625732

Это если через Guzzle - там под капотом, если я не ошибаюсь древний как мамонт multi_curl, который я ещё лет 10, как минимум, назад использовал. Для чего-то более современного нужно немного глубже копнуться в reactPHP или что-то подобное, но это могло занять больше времени.


Ну, и чтобы красивее, по-хорошему, нужно было бы парсить дом через какую-то более красивую по синтаксису библиотеку (если не ошибаюсь Crawler от Symfony подошёл бы, но у меня в докере какой-то вообще минимальный набор экстеншенов для php, нужно было добавлять, а мне лень было, ну а composer ругнулся).

Dreammaker
На сайте с 20.04.2006
Offline
570
#23
что-то при редактировании выдаёт кусок отдельным постом.
D
На сайте с 28.06.2008
Offline
1101
#24
multi_curl у меня тоже замечально работал на 1-10 записей. Когда пошли сотни и тысячи начались проблемы, зависания, пропуски.... лень было разбираться в проблеме.
WS
На сайте с 01.11.2008
Offline
136
#25
Dram #:
multi_curl у меня тоже замечально работал на 1-10 записей. Когда пошли сотни и тысячи начались проблемы, зависания, пропуски.... лень было разбираться в проблеме.
да, для организации локальной многопоточности multi_curl плохо подходи

T7
На сайте с 19.09.2018
Offline
63
#26
Dreammaker #:
Ну, и чтобы красивее, по-хорошему,
Отлично. Сразу возрастает ощущение того,  что серч сила и богат грамотными специалистами.💪
T7
На сайте с 19.09.2018
Offline
63
#27

Мой пост был местами провокационный. Просто, хотелось разбавить абстрактные рассуждения о каких то либах примерами для понимания сути. И, может быть, дойти до каких то практических вариантов применения.


В вебстроительстве главная польза от асинк/авайт, это операции ввода-вывода, когда надо подождать (то, что на скрине 0.455 сек). Это же справедливо для запросов к базе данных. Примеры, что на пхп, что на питоне показывают - да, существенная выгода есть.  Но, зачастую, выгода нивелируется практическим применением.

Dreammaker
На сайте с 20.04.2006
Offline
570
#28
Dreammaker #:
$promises = [
    $function($client->getAsync('1074587')),
    $function($client->getAsync('1074587')),
];

Тут почему-то серч съел кусок урла при редактировании поста, как я сейчас заметил. 

Должно быть:

$promises = [
    $function($client->getAsync('https://searchengines.guru/ru/forum/1074587')),
    $function($client->getAsync('https://searchengines.guru/ru/forum/1074587')),
];


timo-71 #:
В вебстроительстве главная польза от асинк/авайт, это операции ввода-вывода, когда надо подождать (то, что на скрине 0.455 сек).


Вот это подождать на бекенде теоретически может быть заменено другими подходами. Гипотетический пример: нам нужно в кабинете мелкооптового продавца получить данные о товарах доступных на складе у оптового продавца, при заходе на страницу мы отправляем куда-то запрос, заносим запрос в очередь, загружаем страницу с неким js-виджетом, на котором написано "Получается информация" и уже он делает запросы к серверу, получая информацию исполнен ли запрос. Или же даже сам виджет может общаться с сайтом оптовика по ajax, web-socket'ам или, наверное, выше рекомендованным  server-sent events.  В этом случае переносим переносим на сторону клиента. 

timo-71 #:
Но, зачастую, выгода нивелируются практическим применением.


Бекенд обычного веба больше синхронный по логике, чем асинхронный. Грубо говоря, сначала получаем информацию о пользователе, а потом смотрим, что ему можно показать. Чем сложнее проект и чем ближе к веб-приложениям, а не вебсайтам, тем больше там места асинхронности. Имхо, естественно. :)

T7
На сайте с 19.09.2018
Offline
63
#29
Dreammaker #:
Грубо говоря, сначала получаем информацию о пользователе, а потом смотрим, что ему можно показать.

Там по дороге, асинхронность можно использовать. Кстати, архитектура питоновских асинхронных фреймворков намекает.

Кусок миддлевари фастапи. (аиохттп похожий принцип: оперируем 3 объектами  app, request, response)

        self.request_parameters(request)
        # request.state.content вначале {}
        response = await call_next(request)
        # request.state.content: оброс по дороге {'title': '****', 'meta': '****', ...}
        self.response_set_headers(request, response)
        return response

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

Совсем просто: (10 запросов по 2мс (20) выполнены за 10 мс) ?  "асинк во всей красе" : "плохой асинк, хотя кругом авайты"


Aisamiery
На сайте с 12.04.2015
Offline
294
#30
Dreammaker #:
Или же даже сам виджет может общаться с сайтом оптовика по ajax, web-socket'ам или, наверное, выше рекомендованным  server-sent events.  В этом случае переносим переносим на сторону клиента. 

Это вариант на самом деле так себе. Вообще есть такие штуки как api gateway, которые могут проксировать запросы, агрегировать их, выполнять синхронно и параллельно, подставлять результат из первого запроса во второй, например мы использует krakend что бы клиент не ходил на кучу микросервисов, а ходил на кракен а кракен уже собирал ответы по grpc от разных микросервисов

Dreammaker #:
Бекенд обычного веба больше синхронный по логике, чем асинхронный. Грубо говоря, сначала получаем информацию о пользователе, а потом смотрим, что ему можно показать. Чем сложнее проект и чем ближе к веб-приложениям, а не вебсайтам, тем больше там места асинхронности. Имхо, естественно. :)

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

KrakenD - Open source API Gateway
KrakenD - Open source API Gateway
  • www.krakend.io
"I'm excited to hear that KrakenD framework is being brought into the family of open source projects managed by the Linux Foundation. I believe this shows the global community the commitment KrakenD has to keeping their technology open source and free to use. With the adoption that already exists, and this new promise towards the future, I...
Разработка проектов на Symfony, Laravel, 1C-Bitrix, UMI.CMS, OctoberCMS
1 23

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий