Как ускорить Laravel-приложение: параллельные API-запросы через Http::pool и Http::batch

В современных веб-приложениях почти всегда есть потребность общаться с внешними сервисами, будь то Stripe для платежей, OpenAI для обработки данных или CRM-система. Проблема в том, что традиционный последовательный HTTP-вызов тормозит работу: если нужно выполнить три API-запроса по одному, и каждый занимает 1 секунду, пользователь ждёт ~3 секунды. В продакшене такого ожидания проще избегать.

К счастью, Laravel предлагает инструменты для конкурентных запросов к API, позволяя отправлять сразу несколько запросов параллельно и значительно сокращать общее время ответа. Разберём главные подходы, Http::pool и Http::batch, с примерами и рекомендациями.

Предположим, ваш дашборд должен получить данные из трёх систем:

  • GitHub

  • Погодного API

  • Внутренней статистики

Если отправлять запросы по очереди, общее время зависит от суммы всех задержек. С Http::pool они стартуют одновременно, и общее время ≈ длительность самого медленного запроса. Это даёт колоссальный выигрыш в производительности, особенно при медленных API.

1. Http::pool - быстрый параллельный пул запросов

Метод Http::pool() позволяет объединить несколько HTTP-запросов в один "пул" и выполнить их параллельно. Это удобно, когда нужно получить данные из нескольких источников без сложной логики обработки прогресса.

Пример: параллельный GET-запрос

use Illuminate\Http\Client\Pool;
use Illuminate\Support\Facades\Http;

$responses = Http::pool(fn (Pool $pool) => [
    $pool->as('github')->get('https://api.github.com/users/laravel'),
    $pool->as('weather')->get('https://api.weather.com/v3/today'),
    $pool->as('stats')->withToken('secret-key')->get('https://internal.metrics/v1/usage'),
]);

Как работать с ответами

if ($responses['github']->ok()) {
    $githubData = $responses['github']->json();
}

// Обработка ответа с проверкой успеха
$weather = $responses['weather']->successful()
    ? $responses['weather']->json()
    : ['temp' => 'N/A'];

Почему это удобно:

  • Named keys (as('github')) позволяют обращаться к ответам по ключам, а не по индексам массива.

  • Можно гибко настраивать каждую часть запроса (заголовки, токены).

  • Запросы выполняются одновременно.

2. Http::batch - продвинутый пакетный пул с колбэками

Если вы хотите не только отправлять набор запросов, но и отслеживать их прогресс, обрабатывать ошибки или логировать события, стоит использовать Http::batch(). Этот метод дает больше контроля над жизненным циклом запросов.

Пример: синхронизация продуктов

use Illuminate\Http\Client\Batch;
use Illuminate\Support\Facades\Http;

$responses = Http::batch(function (Batch $batch) use ($product) {
    return [
        $batch->as('shopify')->post('https://shopify.com/api/products', $product),
        $batch->as('amazon')->post('https://amazon.com/api/listing', $product),
        $batch->as('ebay')->post('https://ebay.com/api/items', $product),
    ];
})
->before(fn (Batch $batch) => logger()->info("Starting sync for {$batch->totalRequests} platforms."))
->progress(fn (Batch $batch, $key, $response) => logger()->info("Synced to: {$key}"))
->catch(fn (Batch $batch, $key, $error) => logger()->error("Error at {$key}: {$error->getMessage()}"))
->finally(fn () => logger()->info("Sync complete."))
->send();

Что дают колбэки

  • before() - логика перед отправкой всех запросов.

  • progress() - отслеживает результат каждого отдельного запроса по мере завершения.

  • catch() - ловит ошибки на уровне конкретных запросов.

  • finally() - выполняется после завершения всего набора.

3. Обработка ошибок и таймаутов

При параллельных запросах важно учитывать задержки и возможные "зависания" внешних API. Если один из сервисов долго отвечает, он может задержать весь пул.

Совет: всегда настраивайте таймауты для каждого запроса:

$pool->as('slow_api')->timeout(2)->get('https://slow.service/data');

Такой подход защитит ваш код от длительных зависаний и сделает поведение более предсказуемым.

Использование Http::pool и Http::batch в Laravel позволяет избавиться от узких мест, связанных с последовательными API-запросами. Переход от последовательного выполнения к параллельному даёт ощутимое повышение скорости и отзывчивости приложений при интеграции с внешними сервисами.

Комментарии (0)

Войдите, чтобы оставить комментарий

Похожие статьи

Простой способ работать с конкурентностью и параллелизмом в Python

Объяснение, как с помощью стандартных средств Python (concurrent.futures) легко решать задачи конкурентности и параллелизма. Приведены практические примеры использования пулов потоков и процессов.

PHP Generators

Статья рассказывает о PHP генераторах - что это, как они работают, зачем нужны и как использовать их в реальных проектах. Примеры включают чтение больших CSV и потоковую обработку данных.

Laravel-Zipstream: потоковая генерация ZIP-архивов без нагрузки на сервер

Обзор пакета laravel-zipstream для потоковой генерации ZIP-архивов в Laravel. Разбираем, как работает стриминг, его преимущества и когда его стоит использовать.

Как добавить SSH-ключ в аккаунт GitHub

Подробное руководство по добавлению SSH-ключа в аккаунт GitHub: генерация ключа, его добавление в агент, копирование и регистрация на сайте GitHub. Практические шаги для безопасного подключения к репозиториям без пароля.