Рейтинг:0

Передача большого файла tmp зависает в прокси-сервере nginx php-fpm

флаг cn

У нас есть сервер, на котором работает сайт WordPress со стеком nginx, установленным serverpilot, на Ubuntu 20 LTS.

Кажется, что очень большие загрузки застревают в передаче между прокси-сервером nginx и PHP, и я пришел к концу того, что знаю, как устранять неполадки, не просто тыкая в них, чтобы посмотреть, что происходит (что редко является хорошим использованием времени или способ двигаться вперед). Насколько я могу судить, я увеличил необходимые тайм-ауты и увеличил все дисковые лимиты, но, очевидно, я все еще что-то упускаю.

Для нашего варианта использования нам нужно разрешить загрузку до 50 ГБ, что у нас работает без проблем в тестовой среде, в которой работает стандартный стек LAMP. У нас нет проблем с файлами меньше ~ 2 ГБ, но все, что больше, может или не может выйти из строя на основе некоторых критериев, которые я не смог отследить. При устранении проблемы в более раннее время время остановки копирования файла казалось произвольным (с успехом до 10 ГБ), но с текущей конфигурацией (см. ниже) оно постоянно останавливается, когда PHP температура файл достигает 2 ГБ.

Когда мы загружаем очень большие файлы, мы можем наблюдать, как входящий временный файл занимает место на диске до тех пор, пока весь файл не появится в памяти. /mnt/tmp/[nginx_tmp_path] (да, свободного места на диске предостаточно). После этого мы видим, что файл копируется в php температура путь, но через несколько секунд файл php температура файл перестает увеличиваться в размере, и процесс копирования зависает. В конце концов, достигается один из 600-секундных тайм-аутов, и регистрируются ошибки (см. ниже). На этом снимке экрана у нас есть завершенная (с точки зрения браузера/конечного пользователя) загрузка 14,8 ГБ, которая зависла при передаче файла tmp примерно на 2 ГБ. Файл tmp PHP перестает расти

В конце 600-секундного периода в журнале ошибок Apache появляется следующее:

(70008) Частичные результаты действительны, но обработка не завершена: [client <MY_IP>] AH01075: Ошибка отправки запроса на: (чтение входной бригады), реферер: https://<THE_URL>/wp-admin/media-new.php

И журнал ошибок nginx сказал следующее:

2512066#0: *9 истекло время ожидания восходящего потока (110: время ожидания соединения истекло) при отправке запроса восходящему потоку, клиент: <MY_IP>, сервер: <INTERNAL_IP>, запрос: "POST /wp-admin/async-upload.php HTTP/ 2.0", исходящий: "http://127.0.0.1:81/wp-admin/async-upload.php", хост: "<THE_URL>", реферер: "https://<THE_URL>/wp-admin/ медиа-new.php"

Важно отметить, что эти сообщения не появляются в файле журнала до тех пор, пока не пройдет 10 минут после того, как загрузка полностью поступит на сервер, то есть через 9 минут или более после того, как копирование файла окажется приостановленным/зависшим. Я убежден, что что-то вызывает зависание копии файла, а затем, в конце концов, достигается тайм-аут - я не верю, что проблема связана с самим тайм-аутом. В промежутке между остановкой копирования файла и появлением в файле журнала ошибки тайм-аута на сервере нет повышенной или необычной активности, и все службы функционируют и реагируют должным образом.

В текущей конфигурации PHP температура файл всегда увеличивается до 2097152 КБ (согласно ду -а), что заставляет меня поверить, что я достиг встроенного ограничения размера файла, которое я еще не обнаружил.

Соответствующие параметры конфигурации сервера nginx: в сервер контекст:

    proxy_connect_timeout 600;
    proxy_read_timeout 600;
    proxy_send_timeout 600;
    proxy_max_temp_file_size 51200 м;

    fastcgi_connect_timeout 600;
    fastcgi_read_timeout 600;
    fastcgi_send_timeout 600;
    fastcgi_request_buffering выключен;

    keepalive_timeout 600;
    send_timeout 600;

    client_max_body_size 0;
    client_body_temp_path /mnt/tmp;
    client_body_in_file_only чистый;

Конфигурация Apache VirtualHost:

    Заголовок RequestReadTimeout = 0, тело = 0
    Таймаут 3600
    Прокситаймаут 3600

И, наконец, конфигурация PHP:

memory_limit = -1
максимальное_время_исполнения = 0
max_input_time = -1
post_max_size = 50G
upload_max_filesize = 50G
default_socket_timeout = -1

Я в недоумении относительно того, что может быть причиной симптома, который я вижу.Любые указатели приветствуются!

Дополнительные примечания: Симптомы заставляют меня чувствовать, что это не имеет значения, но если это так... Сайт работает через WP Rocket, но нет внешнего прокси-сервиса, такого как CloudFlare.

ОБНОВИТЬ: я добавил эти строки в конфиг nginx:

    прокси_http_версия 1.1;
    proxy_set_header Соединение "";

Это немного изменило симптом, но не решило проблему. С этим изменением поведение вернулось к тому, что я объяснял ранее, и передача файлов останавливается в непредсказуемом месте. Первый пример ниже остановился на 3823176 КБ, а второй остановился на 3264364 КБ. Причина разницы в поведении мне непонятна, но стоит сообщить. введите описание изображения здесь введите описание изображения здесь

ОБНОВЛЕНИЕ 2: я смог окончательно связать это с проблемой передачи температура файл между nginx и php, но я не могу определить конкретную вещь, которая вызывает зависание процесса.

Мы можем пропустить прокси nginx и использовать только PHP температура добавив эти строки в конфиг nginx:

    прокси_буферизация выключена;
    proxy_request_buffering выключен;

В этой конфигурации файлы попадают непосредственно в /mnt/tmp/php<RND_STR> и когда загрузка завершена, наше приложение правильно выбирает файл из температура и выполняет свои задачи.

Однако это замедляет загрузку примерно до 1/3 доступной пропускной способности, поэтому это не очень хорошее решение. Однако это доказывает, что это не проблема приложения.

Итак, вот что происходит:

  1. Пользователь загружает большой файл (максимум 50 ГБ)
  2. Файл приходит в nginx температура локация целиком
  3. Делается попытка скопировать файл из nginx температура в PHP температура - процесс копирования остановится в течение нескольких секунд где-то непредсказуемо, но между 3ГБ и 10ГБ. [3b] В настоящее время мы можем видеть оба температура файлы и PHP температура файл содержит количество байтов, которое должно увеличиваться, пока не сравняется с размером файла nginx. температура файл, но это не так.Оба файла будут оставаться как есть до тех пор, пока не будет достигнут один из 600-секундных тайм-аутов (см. выше), затем в файлах журнала появится ошибка, и оба температура файлы исчезают. [3c] Если размер файла менее 3 ГБ, он будет работать каждый раз. Если файл больше 3 Гб, то иногда он будет работать, а иногда нет - чем меньше файл, тем больше шансов, что он сработает.
  4. Обход nginx температура работает полностью, как и ожидалось, за исключением того, что загрузка медленная.

Что-то определенно зависает во время температура передача файлов между nginx и PHP, когда файлы ужасно огромные, и я хотел бы выяснить, что это такое.

Michael Hampton avatar
флаг cz
Стоит спросить, почему приложению PHP требуется более 600 секунд для обработки файла.
Chris Ostmo avatar
флаг cn
Я увеличил все тайм-ауты, потому что ожидаю, что передача файла размером 50 ГБ займет больше, чем 60 секунд по умолчанию. Это не обработка PHP, которая истечет по тайм-ауту - передача временного файла приведет к истечению времени ожидания прокси-сервера. Я, по общему признанию, слишком широко открылся в поисках решения.
Chris Ostmo avatar
флаг cn
... Однако PHP не требует 600 секунд для обработки файла - что-то останавливается на несколько секунд в копии файла, а 600 секунд - это просто когда он перестает ждать и выдает ошибку. Наше PHP-приложение не имеет возможности начать работу с файлом до тех пор, пока оно не будет перемещено из `tmp`, а это не то состояние, которого мы достигаем. (извините, пытался отредактировать свой оригинальный комментарий, но было слишком поздно)
Michael Hampton avatar
флаг cz
Хм. Ну, все, что я действительно могу сказать из опубликованных ошибок, это то, что nginx, похоже, успешно передал его Apache, а Apache не смог передать его PHP. Для меня это делает главным подозреваемым код PHP, который обрабатывает загрузку. Вы должны привлечь разработчика приложения. Но некоторые другие вещи выглядят немного странно. Вы смонтировали отдельные файловые системы для временных файлов? Какой у них тип файловой системы?
Chris Ostmo avatar
флаг cn
Я разработчик, и эта ошибка возникает из обычного диалогового окна загрузки мультимедиа WordPress, поэтому здесь нет никакого кода, который не используется многими людьми. Файл никогда полностью не завершает передачу от tmp nginx к tmp PHP, поэтому я не верю, что приложение может мешать. Да, папка `tmp` смонтирована на отдельном разделе ext4. Кроме того, изменение поведения при изменении конфигурации сервера не согласуется с ошибкой приложения.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.