WooCommerce REST API: как реализовать логику повторных запросов при ошибке 429 Too Many Requests

Диагностика проблемы: почему возникает ошибка 429 Too Many Requests

Ошибка 429 означает, что сервер WooCommerce ограничивает частоту запросов к REST API, чтобы предотвратить перегрузку. Это часто случается при массовой автоматизации заказов, обновлении статусов или синхронизации товаров. Сервер посылает заголовок Retry-After с указанием времени, через которое можно повторить запрос.

Чтобы проверить, что именно вызывает ошибку, можно включить логирование REST API запросов, либо использовать инструменты отладки, например, Postman или curl с параметром -v для просмотра ответа сервера и заголовков.

Пошаговое решение: реализация логики повторных запросов с экспоненциальной задержкой

1. Обработка ответа с ошибкой 429

При получении HTTP 429 нужно считать заголовок Retry-After и отложить повторный запрос.

2. Пример кода на PHP с использованием GuzzleHttp клиент для повторных запросов:

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

function sendRequestWithRetry($url, $options = [], $maxRetries = 5) {
    $client = new Client();
    $attempt = 0;
    $delay = 1; // начальная задержка в секундах

    while ($attempt < $maxRetries) {
        try {
            $response = $client->request('GET', $url, $options);
            return $response;
        } catch (RequestException $e) {
            if ($e->getResponse() && $e->getResponse()->getStatusCode() === 429) {
                $retryAfter = $e->getResponse()->getHeaderLine('Retry-After');
                $retryAfter = is_numeric($retryAfter) ? (int)$retryAfter : $delay;
                sleep($retryAfter);
                $delay *= 2; // экспоненциальная задержка
                $attempt++;
            } else {
                throw $e; // другие ошибки пробрасываем
            }
        }
    }
    throw new Exception('Max retries exceeded for request to ' . $url);
}

3. Интеграция с WooCommerce REST API

При работе с WooCommerce REST API лучше использовать официальную библиотеку Automattic/WooCommerce. Вот пример с повторной отправкой запроса обновления заказа:

use Automattic\WooCommerce\Client;

$woocommerce = new Client(
    'https://example.com',
    'ck_xxxxxxx',
    'cs_xxxxxxx',
    [
        'version' => 'wc/v3',
        'timeout' => 10,
    ]
);

function updateOrderStatusWithRetry($woocommerce, $orderId, $data, $maxRetries = 5) {
    $attempt = 0;
    $delay = 1;

    while ($attempt < $maxRetries) {
        try {
            return $woocommerce->put("orders/{$orderId}", $data);
        } catch (Exception $e) {
            $response = $e->getResponse();
            if ($response && $response->getStatusCode() === 429) {
                $retryAfter = $response->getHeader('Retry-After');
                $retryAfter = !empty($retryAfter) && is_numeric($retryAfter[0]) ? (int)$retryAfter[0] : $delay;
                sleep($retryAfter);
                $delay *= 2;
                $attempt++;
            } else {
                throw $e;
            }
        }
    }
    throw new Exception('Превышено максимальное количество попыток обновления заказа');
}

Проверка результата после внедрения

  • Отправьте массовые запросы к WooCommerce REST API, например, обновление статусов заказов.
  • Проверьте логи сервера и клиентские логи, что при получении 429 запросы откладываются, а не падают сразу.
  • Убедитесь, что скрипты не завершаются с ошибкой, а успешно завершают работу после нескольких попыток.

Частые ошибки и как исправить

  • Игнорирование заголовка Retry-After: приводит к немедленным повторным запросам и новым ошибкам 429. Используйте значение из заголовка.
  • Отсутствие лимита повторных попыток: скрипт может зациклиться. Всегда устанавливайте максимальное число попыток.
  • Неправильная обработка исключений: ловите только ошибки 429, другие ошибки должны быть проброшены для отладки.
  • Слишком маленькие задержки: увеличивайте задержку экспоненциально, чтобы снизить нагрузку и вероятность повторных ошибок.

Практические советы по производительности и безопасности

  • Кэшируйте ответы API, если данные не меняются часто — снизит число запросов.
  • Используйте очередь задач (WP Cron или внешние сервисы) для равномерного распределения запросов во времени.
  • Ограничивайте объем данных в запросах через параметры фильтрации, чтобы уменьшить нагрузку.
  • Обновляйте WooCommerce и сервер — старые версии могут иметь менее эффективную защиту от DoS.

Сравнение подходов к повторным запросам

ПодходПлюсыМинусы
Игнорировать 429 и не повторятьПростота реализацииЧастые сбои, потеря данных
Фиксированная задержка (например, 1 секунда)Лучше, чем ничегоНе учитывает серверные рекомендации, может быть слишком мало или много
Чтение Retry-After и экспоненциальная задержкаОптимально, уважает сервер и снижает нагрузкуСложнее реализовать
Использование очередей и отложенных задачМаксимальная стабильность и масштабируемостьТребует дополнительной инфраструктуры

Шаблоны для WP Плагины для WP