Использование cURL в PHP имеет свою не очень приятную особенность - обычный запрос сделанный curl-ом, что из fpm/apache, что из cli может привести к серьезной проблеме в работе вашего backend. Выглядит механизм возникновения проблемы, возникающей в случае, когда запрос curl-ом делается прямо из "запроса" в fpm/apache:

  1. Пул процессов php-fpm имеет ограниченное кол-во процессов
  2. Новый запрос обрабатывается свободным процессом. Если свободных процессов нет, то запрос ждет в очеререди 10 секунд, если процессы не освободились, то php-fpm отдает ответ со статусом 502.
  3. Освобождаются процессы PHP-FPM:
    1. Когда завершают обработку запроса
    2. Процессы могут освобождатся принудительно, по ограничению времени max_execution_time, но это время влияет только на php-код, а не на код модулей (таких как curl)
  4. Модуль curl к php имеет баг: если таймаут запроса не указан явно, то по умолчанию он установлен "в бесконечность"

Имея проблему (4) + ситуацию с тем что php не может ограничить время работы curl (3.2) и механизм работы fpm (1+2), ко всем curl-запросам необходимо установить тамаут запроса, иначе повисшие запросы могут занять весь пул процессов php-fpm и каждый новый запрос будет обрабатыватся с ответом 502.

В настройках curl их имеется следующие таймауты:

  1. CURLOPT_CONNECTTIMEOUT - время установления tcp-соединения (не имеет смысла более 5и секунд, т.к. в условиях сети где соединение не может открытся за 5 секунд, получить http ответ, или даже полноценно отправить запрос можно с довольно низкой вероятностью)
  2. CURLOPT_TIMEOUT - его нужно выставить в допустимое значение в секундах: это время установления соединения + время отправки запроса + время ответа до его получения. Более одной минуты в случае работы таких curl прямо из web (fpm/apache) т.к. скорее всего будет возвращен ответ 504 (nginx не получил ответ от php более чем за минуту), а в случае запуска из cli его требуется установить в максимально допустимое.

В случае работы cli

Ситуация проще, но будет иметь свои побочные эфекты в зависимости от варианта запуска таких cli-комманд:

  • Если команда запускается с блокировкой (не более одного экземпляра запущено одновременно), то новый экземпляр не сможет запустится до момента пока процесс не будет убит (kill).
  • Если команда запускается по крону и без блокировки - то таких процессов наплодится много: старые процессы не завершаются, новые порождаются: это займет ram, упрется в ограничение по количеству подключений к базе данных, если они имеются.

P.S.

Архитектурно некорректно ипользовать curl прямо из web (fpm/apache), т.к. это устанавлияет прямую связку между запросом пользователя из браузера + процессом + запросом с помощью curl во вне. Каждый из этих запросов имеет свои ограничения по таймаутам и эта конструкция может существовать стабильно только в идельных условиях (RAM на процессы никогда не закончится + сеть между сервером и клиентом идеальна + запрос curl обрабатывается очень быстро + curl всегда надежно получает ответы).

P.S.2.

Абсолютно так же некорреткно делать такие запросы не только их php с использованием fpm/apache, но и других языков и серверов, в т.ч. nodejs/erlang/go и других - асинхронность экономит RAM, но не повышает условий сети, которые к сожалению реальны и не идеальны

 


Проблемы WebSocket в средней полосе России

Протокол WebSocket имеет свои преимущества и свои недостатоки: детальный разбор

Nginx, Php-Fpm и что это вообще?

Что такое php-fpm и зачем он нужен более-менее посещаемым проектам? Какие неприятности несет в себе переход с apache на fpm? Какие проблемы решает реально, а какие - надумано?

Почему балансировщик http нужно размещать в другом сегменте

И снова о маленьких сетевых фокусах ради надежности работы web-сервисов

Сводная система мониторинга

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

Ошибка HTTP 502 Bad Gateway

Nginx возвращает статус ответа HTTP протокола 502 ровно в одном случае - он не смог достучатся до backend-сервера.

LetsEncrypt: делаем фальшивый cert своими руками

Имеется такое явление набравшее свою популярность, как letsencrypt/certbot. Он выдает ssl-сертификаты автоматически и всем подряд. В целом это его основная проблема.