Вопрос: Почему при монтировании NFS используется sync
опция вызывает nginx и / или Chrome (и только Хром; не Safari, Firefox, Edge или curl) для фрагментации или перезапуска загрузки файла?
Немного предыстории:
У меня есть nginx перед кластером серверов. Мы добавили загрузку файлов, и мы используем nginx для обработки загрузки, а затем передаем загруженное тело файла через его заголовок X-FILE.
До недавнего времени мы обрабатывали только загрузки на сервере nginx из-за проблем с другими серверами приложений в кластере, которые не могли получить доступ к client_body_temp_path
(/tmp
в таком случае).
Мы работаем на AWS, поэтому я подготовил EFS (он же NFS) и смонтировал его в /mnt/efs
а затем изменил nginx client_body_temp_path
указать на /mnt/efs/tmp
.
Я установил общий ресурс NFS на всех серверах приложений, и теперь они могут получить доступ к загрузкам файлов на /mnt/efs/tmp
, но загруженные файлы часто имеют нулевую длину, когда они изначально читаются другими клиентами из-за асинхронной записи NFS.
Я изменил монтирование NFS только на сервере nginx, поэтому он смонтирован с помощью sync
:
Начальное крепление:
example.eu-west-1.amazonaws.com:/ /mnt/efs nfs4 vers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,_netdev,nofail
Новое средство передвижения:
example.eu-west-1.amazonaws.com:/ /mnt/efs nfs4 vers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,_netdev,nofail,sync
Я перемонтировал общий ресурс и попробовал несколько загрузок и счастливых дней, другие клиенты NFS видят непустые файлы в /mnt/efs/tmp
.
Но после дополнительного тестирования выяснилось, что загруженные файлы размером более 10 МБ получают перезапускается или блокируется Chrome.
Что случается:
nginx начинает получать загрузку (в видео ниже, Я отправляю файл размером 32,7 МБ), но при 6,4 МБ начинается новая загрузка, а затем в конечном итоге nginx решает, что клиент прекратил отправку, поэтому проблемы а 499
что приводит к тому, что Chrome прерывает загрузку, и все это не удается. Вы можете видеть, как все это происходит здесь, поскольку я watch
файлы, поступающие в /mnt/efs/tmp
:
http://jay.gooby.org/media/video/chrome%20failing.mp4
Первоначально загрузка выглядит как 0000000006
но затем, когда он достигнет 6.4M, вторая загрузка 0000000007
начинается (но 0000000006
продолжается до 12M), а затем, когда 0000000007
хиты 6,4, треть, 0000000008
начинается (0000000007
продолжается до 12М). однажды 0000000008
Hit 12M ngingx выдает 499
и Chrome прерывает загрузку.
У других юзерагентов такой проблемы нет. Я могу загрузить тот же файл в Safari, Firefox и curl. У Chrome на Mac и Windows одинаковая проблема.
Здесь curl отправляет файл без проблем: он приходит как 0000000010
один файл 32M:
http://jay.gooby.org/media/video/curl%20working.mp4
Немного оторвав волосы, я удалила sync
опция монтирования NFS на сервере nginx, и вот, файлы, загруженные с помощью Chrome, поступают одним куском как один файл. Так что же дает?
nginx находится за эластичным IP-адресом, но не за ELB, и загрузка выполняется по http2.
nginx скомпилирован с --with-threads
вариант
Обновление 1: Это значение в 6,4 МБ казалось значительным, поскольку именно с этого момента начинался / перезапускался каждый новый фрагмент загрузки. 6.4 МБ - это 51200000 бит, что кажется вполне конкретным значением ...
Начальные байты трех файлов идентичны, поэтому создается впечатление, что Chrome решил начать повторную отправку с точки 6,4 МБ: