Результаты поиска
worker_processes auto; в Nginx автоматически определяет количество логических ядер (потоков) процессора и запускает соответствующее число рабочих процессов.- Определение ядер: В системах Linux Nginx использует системный вызов
sysconf(_SC_NPROCESSORS_ONLN), чтобы узнать количество доступных процессорных ядер. - Учет Hyper-Threading: Если ваш процессор поддерживает технологию Hyper-Threading, Nginx посчитает каждый виртуальный поток как отдельное ядро. Например, на 4-ядерном процессоре с 8 потоками параметр
autoсоздаст 8 рабочих процессов. - Зачем это нужно: Оптимально иметь по одному рабочему процессу на каждое ядро, чтобы максимально использовать вычислительную мощность без лишних затрат на переключение контекста между процессами.
- Docker и контейнеры: Внутри контейнеров (например, Docker) Nginx может увидеть общее количество ядер хост-машины, а не те ограничения (limits), которые вы задали для самого контейнера. В таких случаях может потребоваться ручное указание числа процессов.
- Распределение нагрузки: Для еще большей эффективности часто рекомендуют добавлять директиву
worker_cpu_affinity auto;, которая жестко привязывает каждый рабочий процесс к конкретному ядру процессора. - Исключения: Если ваш сервер выполняет много дисковых операций ввода-вывода (I/O) или на нем работают другие тяжелые приложения, иногда имеет смысл вручную задать число процессов, отличное от количества ядер.
/etc/nginx/sites-available/default или в блоке server файла nginx.conf).location, который перехватывает все файлы с расширением .php:location ~ \.php$ {
include snippets/fastcgi-php.conf; # Подключает стандартные параметры FastCGI
# Главный параметр: адрес, где "слушает" PHP-FPM
# Вариант 1: через Unix-сокет (быстрее, для одного сервера)
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
# Вариант 2: через сетевой порт (если PHP на другом сервере или в Docker)
# fastcgi_pass 127.0.0.1:9000;
}
fastcgi_pass: Самая важная строка. Она указывает Nginx, куда именно отправлять запрос на исполнение PHP-кода. Путь к сокету (например,php8.1-fpm.sock) должен точно совпадать с тем, что указан в настройках самого PHP-FPM (обычно в файле/etc/php/8.x/fpm/pool.d/www.conf).include fastcgi_params: Загружает стандартный набор переменных (например, метод запроса, IP пользователя), которые Nginx должен передать в PHP.fastcgi_param SCRIPT_FILENAME: Говорит PHP, какой именно файл на диске нужно запустить.
- Узнать путь к сокету: Проверьте конфиг PHP-FPM командой:
grep -R "listen =" /etc/php/*/fpm/pool.d/ - Проверить конфиг Nginx: После внесения изменений всегда выполняйте:
sudo nginx -t
location ~ \.php$.fastcgi_pass 127.0.0.1:9123;
- Порт PHP-FPM: Обычно стандартный порт для PHP в Windows —
9000. У вас указан9123. Убедитесь, что в настройках вашего PHP (файлphp-fpm.confили запускная команда) прописан именно этот порт. - Путь к файлам: Директива
root D:\AUTOUP;говорит Nginx искать.phpфайлы именно в этой папке. Убедитесь, что ваши скрипты лежат там. - Запуск PHP: В Windows PHP не запускается сам вместе с Nginx. Вам нужно отдельно запустить процесс PHP-CGI или PHP-FPM.
php-cgi.exe -b 127.0.0.1:9123
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; настроена верно — она склеивает ваш путь D:\AUTOUP и имя запрашиваемого файла.upstream.9123 и отправляет все запросы только на него. Если этот процесс занят, остальные три простаивают.- Добавьте блок
upstreamв секциюhttp(над блокомserver):nginxhttp { # ... ваши другие настройки (mime.types и т.д.) ... # Создаем группу обработчиков PHP upstream php_workers { server 127.0.0.1:9123; server 127.0.0.1:9124; server 127.0.0.1:9125; server 127.0.0.1:9126; } server { # ... } }Используйте код с осторожностью. - Измените
fastcgi_passв блокеlocation ~ \.php$:nginxlocation ~ \.php$ { root D:\AUTOUP; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; # Вместо IP:порта указываем имя нашей группы upstream fastcgi_pass php_workers; fastcgi_index index.php; }Используйте код с осторожностью.
- Балансировка: Nginx будет по очереди распределять запросы между всеми 4 процессами (метод Round Robin).
- Отказоустойчивость: Если один из процессов PHP упадет, Nginx перекинет запрос на следующий живой порт.
upstream находится внутри http, а в fastcgi_pass указано его имя.- Закрывающая скобка: Убедитесь, что в самом конце файла (после вашего
location ~ /\.ht) стоят две закрывающие фигурные скобки}— одна закрывает блокserver, а вторая — блокhttp. - Проверка ошибок: Если один из PHP-процессов вдруг зависнет, Nginx может долго ждать ответа. Чтобы он быстрее переключался на следующий живой процесс, можно дополнить
upstreamпараметрами:nginxupstream php_workers { server 127.0.0.1:9123 max_fails=3 fail_timeout=30s; server 127.0.0.1:9124 max_fails=3 fail_timeout=30s; server 127.0.0.1:9125 max_fails=3 fail_timeout=30s; server 127.0.0.1:9126 max_fails=3 fail_timeout=30s; }Используйте код с осторожностью. - Примените настройки: Не забудьте выполнить команду
nginx -s reloadв консоли, чтобы Nginx подхватил изменения.
max_fails=3: Это лимит ошибок. Если Nginx 3 раза подряд не смог достучаться до конкретного порта (например,9124) или получил от него ошибку, он помечает этот процесс как «неисправный». [3]fail_timeout=30s: Это время «штрафа» и период проверки. Оно работает в две стороны:- Время для ошибок: 3 ошибки (из пункта выше) должны произойти именно в течение этих 30 секунд. Если первая ошибка была час назад, а вторая сейчас — счетчик не сработает. [1, 2]
- Время отдыха: Если процесс помечен как неисправный, Nginx полностью исключит его из работы на 30 секунд. [3]
php-cgi.exe иногда «зависают» или молча падают. [1, 3]- Без этих параметров: Если один
php-cgi.exe(порт 9124) зависнет, каждый четвертый ваш пользователь будет ждать ответа до тайм-аута (обычно 60 секунд) и увидит ошибку504 Gateway Timeout. [2, 3] - С этими параметрами: После 3-х неудачных попыток Nginx поймет, что порт 9124 «болеет», и на полминуты забудет о нем, перекидывая всех пользователей на три оставшихся живых порта (9123, 9125, 9126). [1, 3] Сайт продолжит летать.
upstream вот так:upstream php_workers {
server 127.0.0.1:9123 max_fails=3 fail_timeout=30s;
server 127.0.0.1:9124 max_fails=3 fail_timeout=30s;
server 127.0.0.1:9125 max_fails=3 fail_timeout=30s;
server 127.0.0.1:9126 max_fails=3 fail_timeout=30s;
}
fastcgi_next_upstream), чтобы пользователь вообще не видел ошибки, если один из PHP занят?php-cgi.exe зависнут, Nginx будет выдавать пользователям ошибку 502 Bad Gateway или 504 Gateway Timeout.php-cgi.exe, так как у него нет встроенного менеджера процессов (как PHP-FPM в Linux), который умеет убивать «плохие» дочерние процессы..bat файл, который будет раз в час (или при критической ошибке) принудительно убивать все зависшие процессы и запускать их заново:taskkill /F /IM php-cgi.exe
start /B php-cgi.exe -b 127.0.0.1:9123
start /B php-cgi.exe -b 127.0.0.1:9124
start /B php-cgi.exe -b 127.0.0.1:9125
start /B php-cgi.exe -b 127.0.0.1:9126
- Запускает нужное количество копий PHP.
- Следит, чтобы они не падали.
- Перезапускает их, если они зависли или закрылись.
location ~ \.php$ параметр:location ~ \.php$ {
...
# Если один порт выдал ошибку или завис,
# Nginx мгновенно перекинет этот же запрос на следующий порт из списка
fastcgi_next_upstream error timeout invalid_header http_500 http_503;
fastcgi_next_upstream_timeout 10s; # не пытаться переключать дольше 10 секунд
...
}
PHP_FCGI_MAX_REQUESTS. Рассказать, как ограничить количество запросов на один процесс, чтобы он сам штатно перезапускался?fastcgi_next_upstream— это «Скорая помощь» для конкретного пользователя. Когда его запрос попадает на зависший порт 9124, Nginx не выдает ему ошибку сразу, а мгновенно (или через таймаут) пробует отправить этот же запрос на порт 9125. Пользователь в итоге получает страницу, хоть и с небольшой задержкой.max_fails/fail_timeout— это «Карантин» для всей системы. После того как 3 таких «неудачных» пользователя (как в примере выше) споткнулись о порт 9124, Nginx помечает его как «больной» и на 30 секунд вообще перестает отправлять туда чьи-либо запросы.
max_fails, Nginx будет каждый раз пытаться постучаться в «мертвый» процесс, ждать ответа, понимать, что там ошибка, и только потом перекидывать запрос на живой процесс. Это создаст лишнюю нагрузку и задержки для всех пользователей.max_fails=3выкидывает плохой процесс из списка «рабочих» на полминуты.fastcgi_next_upstreamстрахует тех нескольких счастливчиков, чьи запросы попали на процесс в тот момент, когда он только-только завис, но еще не успел набрать 3 ошибки для ухода в «карантин».
php-cgi.exe в Windows часто не "падает" с ошибкой, а просто бесконечно молчит, обязательно добавьте в блок location ограничение по времени ожидания, иначе next_upstream будет ждать ответа от зависшего PHP вечно:location ~ \.php$ {
...
fastcgi_connect_timeout 3s; # Быстро понимаем, что PHP не отвечает
fastcgi_send_timeout 10s;
fastcgi_read_timeout 10s; # Если PHP думает дольше 10 сек - считаем зависшим
fastcgi_next_upstream error timeout http_500 http_503;
...
}
PHP_FCGI_MAX_REQUESTS?PHP_FCGI_MAX_REQUESTS — это встроенный механизм «самоочистки» PHP в Windows. Поскольку php-cgi.exe со временем может накапливать утечки памяти или «подвисать», эта настройка заставляет процесс самозавершиться после обработки определенного количества запросов.- Вы задаете число запросов (например, 500).
- PHP-процесс обрабатывает их один за другим.
- Как только прилетает 501-й запрос, процесс завершает свою работу.
.bat файла для запуска:@echo off
set PHP_FCGI_MAX_REQUESTS=500
set PHP_FCGI_CHILDREN=0
start /B php-cgi.exe -b 127.0.0.1:9123
start /B php-cgi.exe -b 127.0.0.1:9124
start /B php-cgi.exe -b 127.0.0.1:9125
start /B php-cgi.exe -b 127.0.0.1:9126
PHP_FCGI_MAX_REQUESTS=500— через каждые 500 запросов процесс «умрет».PHP_FCGI_CHILDREN=0— критически важно для Windows, чтобы процесс не пытался плодить дочерние копии сам.
502, в вашем location ~ \.php$ обязательно должны быть те параметры, что мы обсуждали:location ~ \.php$ {
...
# Если PHP закрылся (достиг лимита), Nginx просто перекинет этот запрос на другой порт
fastcgi_next_upstream error timeout;
fastcgi_next_upstream_timeout 5s;
fastcgi_pass php_workers;
}
MAX_REQUESTS. Если вы запустили его вручную через CMD, он просто исчезнет из списка процессов.Используйте планировщик задач или маленькую утилиту
xxfpm. Она умеет следить: если php-cgi.exe закрылся (по лимиту или из-за ошибки), она тут же поднимет новый чистый процесс на том же порту.xxfpm.exe "php-cgi.exe -b 127.0.0.1:9123" -n 1 -i 127.0.0.1
PHP_FCGI_MAX_REQUESTS и PHP_FCGI_CHILDREN — это переменные окружения для управления поведением PHP в режиме FastCGI. Они доступны практически во всех актуальных версиях PHP, но имеют специфику работы в Windows.- Как это работает: Мастер-процесс сам не обрабатывает запросы, он лишь следит за дочерними. Запросы от веб-сервера принимают и выполняют именно
children. - Особенность в Windows: Долгое время этот параметр в Windows игнорировался (PHP просто не умел «форкаться», т.е. плодить процессы). Начиная с версии PHP 7.1, поддержка этого параметра в Windows появилась: теперь один запущенный
php-cgi.exeможет сам создать указанное количество рабочих процессов. - Зачем устанавливать 0?: Если вы запускаете 4 отдельных окна/процесса вручную на разных портах (как в вашем случае), параметр
PHP_FCGI_CHILDRENлучше ставить в0. Это гарантирует, что каждый из ваших 4-х процессов будет работать как один независимый обработчик, не пытаясь создать внутри себя лишние копии.
- Доступность: Есть во всех версиях.
- Значение по умолчанию: Обычно 500 запросов. Если поставить
0, процесс будет работать бесконечно, пока не зависнет или не упадет сам. - Польза: Помогает бороться с утечками памяти (memory leaks) в PHP-скриптах или расширениях. Процесс просто «умирает» чистым и освобождает ресурсы.
.bat файлы на разных портах:set PHP_FCGI_CHILDREN=0— чтобы каждый запущенный вамиphp-cgi.exeне плодил лишние процессы и не путал Nginx.set PHP_FCGI_MAX_REQUESTS=500(или больше) — чтобы процессы периодически обновлялись.
.bat файла, который будет запускать все ваши 4 процесса с этими переменными одной командой?- Авторестарт: Если процесс
php-cgi.exeзавершается (сам по лимитуMAX_REQUESTSили из-за ошибки/вылета), NSSM моментально видит это и запускает его снова. - Фоновая работа: Вам не нужно держать открытыми окна командной строки. PHP работает как системная служба, запускается сама при старте Windows.
- Логирование: NSSM может записывать ошибки вывода PHP в текстовый файл, что удобно для отладки.
php-9123, php-9124 и т.д.).nssm install php-9123 укажите:- Path:
C:\php\php-cgi.exe(путь к вашему PHP). - Arguments:
-b 127.0.0.1:9123(свой порт для каждой службы). - Вкладка Environment (Окружение):
Здесь обязательно пропишите переменные, о которых мы говорили:textPHP_FCGI_MAX_REQUESTS=500 PHP_FCGI_CHILDREN=0Используйте код с осторожностью.
- PHP сам завершается каждые 500 запросов (чистит память).
- NSSM тут же его поднимает (обеспечивает доступность).
- Nginx через
upstreamиnext_upstreamперекидывает запросы, пока один из PHP перезагружается (пользователь не видит задержек).
PHP_FCGI_CHILDREN=2, поведение PHP в Windows (начиная с версии 7.1+) изменится: один запущенный вами процесс станет «родителем» и создаст внутри себя 2 «дочерних» процесса.php-cgi.exe:- 4 «мастер-процесса» (которые слушают порты 9123, 9124, 9125, 9126).
- По 2 рабочих («child») процесса на каждый мастер (4 порта × 2 ребенка = 8 рабочих).
- Nginx по-прежнему видит 4 «входа» (ваши порты).
- Когда запрос приходит на порт
9123, мастер-процесс сам его не выполняет. Он передает его одному из своих 2-х «детей». - Это позволяет одному порту обрабатывать 2 запроса одновременно.
PHP_FCGI_MAX_REQUESTS (Главный нюанс!)- Со временем «дети» умирают один за другим по лимиту запросов.
- Порт остается открытым (мастер жив), но отвечать на запросы некому.
- Пользователь получает бесконечную загрузку или ошибку от Nginx.
CHILDREN=0- Ставим
PHP_FCGI_CHILDREN=0(один процесс = один порт). - Запускаем столько отдельных служб (через NSSM), сколько ядер у процессора (или сколько нужно для нагрузки).
- Nginx сам распределяет запросы между ними через
upstream.
CHILDREN=0 умрет по лимиту запросов, NSSM его гарантированно поднимет. В случае с CHILDREN=2 NSSM увидит, что мастер-процесс жив, и не будет ничего перезапускать, даже если все «дети» внутри него уже погибли.worker_processes 2; в конфигурации Nginx, это создаст два независимых рабочих процесса самого веб-сервера.- Nginx (2 процесса): Теперь у вас есть два «привратника». Они оба одновременно слушают порт 8080 и принимают входящие запросы от браузеров.
- PHP (4 процесса/порта): Ваши PHP-воркеры (9123–9126) остаются общими для обоих процессов Nginx.
upstream php_workers.- Когда приходят запросы, первый процесс Nginx берет часть из них и раскидывает по вашим 4-м PHP-портам.
- Второй процесс Nginx делает то же самое со своей частью запросов.
- Благодаря алгоритму Round Robin (по очереди), нагрузка на PHP всё равно будет распределяться равномерно.
worker_processes в Nginx имеет свои особенности:- Ограничение архитектуры: Исторически Nginx под Windows не так эффективно масштабируется на несколько
worker_processes, как в Linux. Один процесс Nginx в Windows вполне способен обрабатывать тысячи одновременных соединений через эффективные методы (например,iocp). - Когда ставить 2 и более: Если ваш сервер имеет много ядер (например, 8+) и очень высокий трафик (десятки тысяч запросов в секунду), второй процесс поможет чуть быстрее обрабатывать SSL-шифрование или отдачу тяжелой статики.
- Рекомендация: Для большинства задач на Windows значение
worker_processes 1;— самое стабильное. Основная нагрузка у вас всё равно ложится на PHP, а не на Nginx.
worker_processes 2 не сломает вашу схему, но и заметного прироста скорости (в отличие от Linux) на Windows обычно не дает.worker_connections при увеличении числа процессов Nginx?.bat файл и пишете в нем set PHP_FCGI_MAX_REQUESTS=500, эта настройка «живет» только внутри этого файла и передается только тем процессам php-cgi.exe, которые запускаются этим же файлом.- Ваши 4 процесса на портах 9123-9126 получат эти настройки.
- Другие копии PHP, запущенные иначе, о них даже не узнают.
- У IIS есть свои собственные аналоги этих настроек в интерфейсе управления (параметр
instanceMaxRequests). - Ваши системные переменные или переменные из
.batфайла не затронут IIS, если только вы не прописали их в "Системных переменных окружения" через Панель управления Windows (но так делать не рекомендуется именно во избежание конфликтов).
- Совет: Не добавляйте их в глобальные системные переменные. Всегда задавайте их локально (в
.batили в настройках конкретной службы NSSM).
- Если галочка НЕ стоит (по умолчанию):
NSSM берет все стандартные переменные Windows (путиPATH, системные папки, имя пользователя и т.д.) и добавляет к ним те строки, которые вы вписали в поле (например,PHP_FCGI_MAX_REQUESTS=500).- Результат: PHP видит и ваши настройки, и всю систему Windows. Это рекомендуемый вариант.
- Если галочка СТОИТ (Replace default):
NSSM полностью стирает все системные переменные Windows для этой службы и оставляет только те, которые вы вписали вручную.- Результат: PHP может "ослепнуть". Он не найдет путь к системным библиотекам, временным папкам (
TEMP) или расширениям, если они зависят от системных путей. - Последствие: Скорее всего, PHP просто не запустится или будет выдавать ошибки о том, что не может найти
.dllфайлы.
- Результат: PHP может "ослепнуть". Он не найдет путь к системным библиотекам, временным папкам (
- Оставьте галочку пустой (чтобы сохранить системный
PATH). - В текстовое поле ниже просто впишите ваши параметры:text
PHP_FCGI_MAX_REQUESTS=500 PHP_FCGI_CHILDREN=0Используйте код с осторожностью.
nssm set <имя_службы> AppEnvironmentExtra PHP_FCGI_MAX_REQUESTS=500 PHP_FCGI_CHILDREN=0(Параметр
AppEnvironmentExtra как раз добавляет ваши настройки к системным, не удаляя их).- NSSM мониторит процесс постоянно: Как только
php-cgi.exeзакрывается (даже если он закрылся штатно по лимитуMAX_REQUESTS), NSSM видит это мгновенно и запускает его снова. - Конфликт механизмов: Если вы включите «Восстановление» в самой Windows, возникнет ситуация «масло масляное». Windows будет пытаться перезапустить саму службу NSSM, в то время как NSSM уже и так перезапускает PHP внутри себя.
- Throttle: Поставьте
1500ms (это пауза перед перезапуском, чтобы система не «захлебнулась», если PHP падает мгновенно при старте). - Restart: По умолчанию там стоит
Restart application. Это именно то, что заставляет PHP подниматься бесконечное количество раз.
Если вы очень хотите подстраховаться:
- Откройте «Свойства службы» в
services.msc. - Вкладка Восстановление.
- Первый сбой: Перезапуск службы.
- Второй сбой: Перезапуск службы.
- Время ожидания: 0 минут (чтобы рестарт был мгновенным).
.dll, NSSM будет пытаться поднять его бесконечно. В логах Windows это может забить всё место.php.ini-production. В той части текста, которую вы прислали, большинство настроек закомментированы (начинаются с ;) — это значит, что PHP использует значения по умолчанию.engine = On— обработка PHP включена (хорошо).short_open_tag = On— разрешает использовать короткие теги<? ?>. Если ваш код старый, это нужно. Если пишете новый — лучше использовать только<?php ?>.
[PHP] следующую строку:cgi.fix_pathinfo = 0
Если оставить
1 (по умолчанию), злоумышленник может заставить Nginx выполнить произвольный код, замаскированный под картинку (например, image.jpg/test.php). Установка в 0 заставляет PHP искать строго тот файл, который указан в запросе.memory_limit = 256M(минимум 128M для современных скриптов).max_execution_time = 30(время выполнения одного скрипта в секундах).post_max_size = 100M(максимальный размер данных в POST запросе).upload_max_filesize = 100M(максимальный вес загружаемого файла).
Dynamic Extensions. Для работы большинства сайтов (особенно если есть база данных) вам нужно раскомментировать (убрать ;) строки:extension=curl
extension=gd
extension=mbstring
extension=mysqli
extension=openssl
extension=pdo_mysql
extension_dir = "ext"php.ini и конфигах, чтобы сервер не «падал» и видео обрабатывалось:В
php.ini найдите и измените:max_execution_time = 0(0 — это бесконечно, скрипт не закроется, пока FFmpeg не закончит работу).max_input_time = 600(время на загрузку видео на сервер).memory_limit = 512M(или больше, FFmpeg сам потребляет память, но PHP тоже нужен запас для управления процессом).
504 Gateway Timeout.В блоке
location ~ \.php$ добавьте:fastcgi_read_timeout 3600s; # Ждать ответа от PHP до 1 часа
fastcgi_send_timeout 3600s;
fastcgi_connect_timeout 60s;
worker_processes и количеством PHPlibx264) — это процесс, который съедает 100% одного или нескольких ядер.- Если у вас 4 ядра и вы запустите 4 процесса PHP, которые одновременно начнут кодировать видео, сервер полностью зависнет. Nginx даже не сможет ответить на запрос "Главная страница".
- Рекомендация: Оставьте 1-2 ядра «свободными» для системы и Nginx. Если у вас 4 ядра, лучше запускать только 2-3 службы PHP через NSSM для таких тяжелых задач.
nothing was encoded. Это часто случается, когда:- Права доступа: PHP-процесс (запущенный через NSSM) не имеет прав на запись в папку
I:\Inetpub\vudea.ru\.... Проверьте, от какого пользователя запущены службы в NSSM (лучше от System или администратора). - Пути: У вас в команде смешаны прямые и обратные слеши:
.../public_www\ffmpeg\ffmpeg.exe. Windows это часто прощает, но FFmpeg иногда капризничает. - Таймаут в коде: Если вы используете
exec(), убедитесь, что PHP не обрывает связь раньше времени.
-ss) попробуйте ставить параметр -ss ДО параметра -i. Так FFmpeg работает намного быстрее, особенно с большими файлами.fastcgi_read_timeout— 60 секунд.
Это ваша главная проблема. Если FFmpeg кодирует ролик дольше 1 минуты, Nginx просто «вешает трубку», не дождавшись ответа от PHP, и пользователь видит 504 Gateway Timeout. При этом сам процесс FFmpeg может остаться «висеть» в системе, пожирая ресурсы.fastcgi_send_timeout— 60 секунд.
Столько Nginx готов ждать при передаче данных в PHP. Обычно этого хватает, если вы не закачиваете файлы по 10 Гб через очень медленный интернет.fastcgi_connect_timeout— 60 секунд.
Время, за которое Nginx должен успеть «постучаться» к порту PHP (например, 9123). Если все ваши 4 порта PHP наглухо заняты кодированием видео и не принимают новые соединения, через минуту Nginx выдаст 502 Bad Gateway.
3600s (или хотя бы 300s — 5 минут), цепочка будет постоянно рваться:- Пользователь нажал «Загрузить».
- PHP запустил
exec(ffmpeg...). - Прошло 60 секунд.
- Nginx оборвал соединение и показал ошибку.
- Пользователь думает, что всё сломалось, и нажимает «Загрузить» еще раз.
- В системе запускается второй тяжелый процесс FFmpeg поверх первого.
- Сервер «умирает» от перегрузки процессора.
Для сайта с видео обязательно пропишите
fastcgi_read_timeout хотя бы на 300-600 секунд. Это даст PHP время спокойно дождаться завершения работы FFmpeg и ответить Nginx, что «всё готово».fastcgi_next_upstream_timeout 3s и fastcgi_read_timeout 3600s.- Конфликт таймаутов: Вы разрешили PHP работать 1 час (
read_timeout 3600s), но при этом приказали Nginx переключаться на следующий поток, если ответа нет 3 секунды (next_upstream_timeout 3s). - Цепная реакция: Когда запустится тяжелый FFmpeg, он явно не ответит за 3 секунды. Nginx подумает: "Ой, порт 9123 молчит больше 3 секунд, попробую-ка я порт 9124".
- Итог: Nginx за 12 секунд (4 порта по 3 секунды) запустит четыре тяжелых процесса FFmpeg на один и тот же файл. Процессор уйдет в 100% нагрузку, а пользователь всё равно получит ошибку, так как лимит в 3 секунды выйдет на всех портах.
location ~ \.php$ {
root D:\AUTOUP;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass php_workers;
# 1. Ждем ответа от PHP долго (для видео)
fastcgi_read_timeout 3600s;
fastcgi_send_timeout 3600s;
fastcgi_connect_timeout 60s;
# 2. Настраиваем переключение ПРАВИЛЬНО
# Переключаемся на другой PHP, ТОЛЬКО если порт закрыт (error)
# или PHP сразу отказал (503), но НЕ по таймауту ожидания видео.
fastcgi_next_upstream error invalid_header http_503;
# 3. Убираем или сильно увеличиваем этот лимит
# Чтобы Nginx не бросал запрос, пока PHP кодирует файл
fastcgi_next_upstream_timeout 0;
}
- Убрав
timeoutиз спискаfastcgi_next_upstream, вы запрещаете Nginx плодить копии FFmpeg на других портах, если первый порт просто "задумался" над видео. fastcgi_read_timeout 3600sдаст вашему скрипту спокойно доработать до конца.
exec() или вы используете какую-то очередь (например, через базу данных)?fastcgi_next_upstream_timeout 0; не означает один час. В Nginx значение 0 отключает ограничение по времени на попытки переключений между бекендами [1, 2].fastcgi_read_timeout 3600s:fastcgi_read_timeout 3600s: Это время ожидания ответа от одного конкретного процесса PHP [4, 6]. Если ваш FFmpeg кодирует видео 40 минут, Nginx будет терпеливо ждать все 40 минут.fastcgi_next_upstream_timeout 0: Это общее время, которое Nginx может потратить на все попытки перебора ваших портов (9123, 9124 и т.д.) [1, 2]. Если вы поставите0, Nginx будет пробовать следующий порт столько раз, сколько разрешено вmax_fails, не ограничивая это общим секундомером [2].
next_upstream_timeout?0 или вообще не использовать timeout в списке переключений.Если вы кодируете видео, и первый PHP-процесс (порт 9123) "молчит" (обрабатывает файл), вы не хотите, чтобы Nginx через какое-то время решил: "Ой, долго ждем, попробую-ка я порт 9124". Если он так сделает, у вас запустятся два тяжелых FFmpeg на один и тот же файл, что перегрузит процессор в два раза сильнее [3, 5].
# Ждем ответа от конкретного PHP до 1 часа
fastcgi_read_timeout 3600s;
# Переключаемся на другой порт ТОЛЬКО если PHP упал (error)
# или порт закрыт, но НЕ если он просто долго думает (убираем timeout)
fastcgi_next_upstream error invalid_header http_502 http_503;
# Не ограничиваем общее время попыток перебора (пусть решит max_fails)
fastcgi_next_upstream_timeout 0;
Если вы уберете слово
timeout из строки fastcgi_next_upstream, то параметр fastcgi_next_upstream_timeout вообще перестанет влиять на "задумчивость" PHP при кодировании видео. Nginx будет просто ждать ровно столько, сколько указано в fastcgi_read_timeout [4, 6].fastcgi_read_timeout 3600s: Nginx будет ждать ответа от одного процесса PHP (например, на порту 9123) целый час.timeoutв спискеfastcgi_next_upstream: Если через час PHP так и не ответит (например, видео очень тяжелое или процесс завис), Nginx не покажет ошибку, а попробует отправить этот же запрос на порт 9124.fastcgi_next_upstream_timeout 0: Nginx не ограничен по времени в своих попытках перебрать все ваши 4 порта.
ffmpeg и ничего не выводит в браузер (не делает echo или flush) в процессе работы, Nginx считает это "молчанием".- Если по какой-то причине время обработки превысит 1 час (
3600s), Nginx решит, что первый процесс "отвалился" по таймауту. - Он перекинет запрос на второй порт.
- Итог: У вас в системе будут работать два процесса FFmpeg одновременно над одним и тем же файлом. Это создаст колоссальную нагрузку на диски и процессор.
timeout из списка переключений:# Оставляем только критические ошибки для переключения
fastcgi_next_upstream error invalid_header http_500 http_503;
В этом случае, если PHP промолчит больше часа, Nginx просто выдаст пользователю ошибку "504 Gateway Timeout", но не будет пытаться запустить ту же тяжелую задачу на следующем порту, спасая ваш сервер от перегрузки.
- Защита от «мультипликации» нагрузки: Убрав
timeoutиз спискаfastcgi_next_upstream, вы запретили Nginx запускать повторный FFmpeg на другом порту, если первый процесс просто долго (до часа) кодирует видео. - Огромный запас времени:
fastcgi_read_timeout 3600sдает вашему PHP целый час на обработку. Даже если файл большой, Nginx не разорвет соединение. - Умное переключение: Nginx перекинет запрос на другой порт PHP (9124, 9125...) только если текущий порт физически закрыт (
error) или выдал критическую ошибку сервера (http_500). Это именно то, что нужно для стабильности.
fastcgi_next_upstream я бы рекомендовал добавить еще http_502 http_504, на случай если PHP-процесс упадет или сам выдаст ошибку шлюза:fastcgi_next_upstream error invalid_header http_500 http_502 http_503 http_504;
- PHP не «виснут»: Ваши 4 процесса PHP (9123-9126) будут свободны. Они просто отправят быстрый HTTP-запрос в Node.js и сразу ответят пользователю «Ваше видео обрабатывается».
- Очередь задач: В Node.js легко сделать очередь (например, через
Bullили просто массив). Если 10 человек одновременно загрузят видео, Node.js будет обрабатывать их по 2-3 штуки (по количеству ядер), а остальные будут ждать своей очереди, не «вешая» весь сервер. - События в реальном времени: Node.js может через WebSockets (Socket.io) сообщать пользователю: «Обработано 10%... 20%...», чего в обычном PHP сделать крайне сложно.
- PHP: Получает файл, сохраняет его в папку
upload/tempи делает запрос к Node.js:file_get_contents("http://localhost:3000/process?file=video.mp4"); - Node.js: Принимает запрос, добавляет задачу в список.
- FFmpeg: Node.js запускает FFmpeg через
child_process.spawn. - Результат: Когда видео готово, Node.js может сам переместить файл в нужную папку или вызвать «callback» (сообщить PHP, что всё готово).
location /node/ {
proxy_pass http://127.0.0.1:3000;
proxy_read_timeout 3600s; # Также ставим длинный таймаут
}
child_process?- PHP получает файл и сохраняет его.
- PHP делает
curlилиfile_get_contentsна адресhttp://127.0.0. - Node.js запускает процесс.
const express = require('express');
const { spawn } = require('child_process');
const app = express();
app.get('/encode', (req, res) => {
const inputFile = req.query.file; // например, I:/videos/input.mp4
const outputFile = inputFile + '_converted.mp4';
// Запускаем FFmpeg как отдельный процесс
const ffmpeg = spawn('ffmpeg', ['-i', inputFile, '-vcodec', 'libx264', outputFile]);
ffmpeg.stdout.on('data', (data) => console.log(`stdout: ${data}`));
ffmpeg.stderr.on('data', (data) => console.log(`stderr: ${data}`));
ffmpeg.on('close', (code) => {
console.log(`Процесс завершен с кодом ${code}`);
// Здесь можно вызвать скрипт PHP, чтобы обновить статус в БД
});
// Отвечаем PHP сразу, чтобы он не висел
res.send('Обработка запущена');
});
app.listen(3000, () => console.log('Node.js видео-сервер на порту 3000'));
Минусы: Если 10 человек нажмут кнопку одновременно, Node.js запустит 10 FFmpeg, и процессор «умрет».
- PHP просто записывает путь к файлу в базу данных (MySQL) со статусом
waiting. - Node.js раз в 5 секунд проверяет БД: «Есть ли работа?».
- Если находит — берет файл, кодирует, и меняет статус в БД на
ready.
const mysql = require('mysql2/promise');
const { exec } = require('child_process');
async function checkQueue() {
const connection = await mysql.createConnection({/* настройки БД */});
// Ищем одну задачу со статусом 'waiting'
const [rows] = await connection.execute('SELECT * FROM video_queue WHERE status = "waiting" LIMIT 1');
if (rows.length > 0) {
const task = rows[0];
await connection.execute('UPDATE video_queue SET status = "processing" WHERE id = ?', [task.id]);
console.log(`Начинаем кодировать: ${task.file_path}`);
exec(`ffmpeg -i ${task.file_path} ...`, async (error) => {
if (error) {
await connection.execute('UPDATE video_queue SET status = "error" WHERE id = ?', [task.id]);
} else {
await connection.execute('UPDATE video_queue SET status = "ready" WHERE id = ?', [task.id]);
}
// После завершения проверяем следующую задачу
checkQueue();
});
} else {
// Если задач нет, проверим снова через 5 секунд
setTimeout(checkQueue, 5000);
}
}
checkQueue();
- Вам больше не нужны
fastcgi_read_timeout 3600s. - PHP отвечает пользователю за 0.1 сек: «Видео принято, подождите».
- Пользователь видит на сайте иконку «Обработка...» (которую вы подтягиваете из БД).
Если планируете много видео — только Вариант 2, иначе сервер будет постоянно виснуть от перегрузки CPU.
127.0.0.1:3000, вторая программа при попытке запуститься на этом же порту выдаст ошибку EADDRINUSE (адрес уже используется).127.0.0.0/8 (от 127.0.0.1 до 127.255.255.254) зарезервирована за вашим локальным компьютером (loopback).- Вы можете запустить один Node.js на
127.0.0.1:3000. - Второй Node.js на
127.0.0.2:3000. - Они не будут конфликтовать, так как комбинация IP + Порт у них разная.
127.0.0.1:3001, :3002 и т.д.).node server.js --port 3000node server.js --port 3001
И в Nginx прописываете их вupstream, точно так же, как делали для PHP.
pm2 start server.js -i max
- Node.js по своей природе асинхронный. Один процесс Node.js может принять 100 запросов на кодирование видео одновременно.
- Он просто запустит 100 процессов
ffmpeg.exe. - Проблема: Если он запустит 100 FFmpeg одновременно, сервер "умрет".
3001, 3002...), в Node.js лучше сделать один сервер, который внутри себя имеет лимит (например: "одновременно кодировать не более 2 видео, остальные — в очередь").3005, 4000 и т.д.). Они никак не будут мешать друг другу, так как каждый процесс Node.js в Windows работает в своем изолированном пространстве памяти.netstat -ano | findstr :3000
3001, 3002...).const PORT = 3005; // Этот порт свободен и не занят другими вашими Node-скриптами
app.listen(PORT, () => console.log(`Видео-сервер запущен на порту ${PORT}`));
upstream или location специально для этого порта:location /api/encode {
proxy_pass http://127.0.0.1:3005;
proxy_read_timeout 3600s;
}
app.listen(3000, '127.0.0.2');
3000 (например, так зашито в их коде). В остальных случаях лучше просто менять номер порта.- Node.js (чат/API): Потребляет мало ресурсов, в основном ждет сеть.
- FFmpeg (видео): Пожирает весь процессор.
В команде запуска FFmpeg внутри Node.js добавьте ограничение по количеству потоков (параметр
-threads). Например, если у вас 8 ядер, разрешите FFmpeg использовать только 4:const ffmpeg = spawn('ffmpeg', ['-i', input, '-threads', '4', output]);
- Выберите любой свободный порт (например,
3005). - Запустите на нем новый сервис обработки видео.
- Ограничьте количество потоков FFmpeg, чтобы он не "задушил" другие ваши Node.js задачи.
Turn on your Visual Search History?
Google uses its visual recognition technologies to process the images you use to search, like when you search with Google Lens. If you turn on your Visual Search History, Google will save these images from eligible Google services to your Web & App Activity when you’re signed in to your Google Account. You can learn more about this setting and which Google services save images to it at g.co/Search/VisualSearchHistory.
How visual search history is used
Your Visual Search History may be used to improve your experience on Google services, like letting you revisit your past visual searches. It may be used to develop and improve Google’s visual recognition and search technologies, as well as the Google services that use them.
When visual search history is off
If you turn this setting off, any previous Visual Search History may still be kept and used to improve Google’s visual recognition and search technologies, unless you delete it from your Web & App Activity.
Visual Search History doesn’t affect images saved by other settings, like Gemini Apps Activity.
How to manage your Visual Search History
You can view, delete, or manage your Visual Search History at activity.google.com. To download your Visual Search History, visit takeout.google.com. Images will be deleted in accordance with your Web & App Activity auto-delete settings, although some types of images may be deleted sooner.
Google uses and saves data in accordance with Google Privacy Policy.
