Использование 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, но не повышает условий сети, которые, к сожалению, реальны и не идеальны.

 

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

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

Капризы WebSocket и при чём здесь костыли

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

Установка PHP и модулей на Ubuntu/Debian

В Debian/Ubuntu это делается легко и просто, зачастую не требуется ничего собирать

Как установить SSL-сертификат

В последнее время многие сайты переезжают на https и получают в связи с этим следующую проблему....

Угадайте самый медленный фреймворк. И это не Laravel

Есть распространенное мнение, что Laravel почти самый медленный фреймворк, что даже его название нужно читать медленно и только одним пользователем на 1 ядро CPU. Но к счастью, это не так

IoT Highload: особенности и подводные камни

Особенности серверных приложений, работающих с сетью IoT-устройств на практике и в теории