За последние 24 часа нас посетили 22004 программиста и 1002 робота. Сейчас ищут 713 программистов ...

Загрузка файлов с использованием прокси nginx

Тема в разделе "PHP для профи", создана пользователем nikola166, 5 фев 2017.

Метки:
  1. nikola166

    nikola166 Новичок

    С нами с:
    5 фев 2017
    Сообщения:
    3
    Симпатии:
    0
    Доброго времени суток. Суть вопроса: Есть приложение на PHP сайт, PHP скрипт который загружает файлы, nginx хост сайта, nginx хост файлового сервера (upstream). На сайте происходит загрузка файлов на путь /upload/. Хост nginx сайта проксирует данный адрес на хост файлового сервера, которых может быть много как мы понимаем (upstream).
    1 Вопрос: Если файл грузится по частям с такой схемой, не получится ли так, что проксирующий хост сайта один раз выберет один файловый сервер из upstream, а для другого кусочка файла выберет другой файловый сервер из upstream.
    2 Вопрос: Если у вас есть другие предложения по организации загрузки файлов, то я буду безумно рад их выслушать.
     
  2. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    А по частям - это как? Если каждая часть грузится через отдельное соединение, то может на разные контент-серверы упасть. Хотя, я давно не копался, есть вероятность, что nginx пробежится про серверам с соответствующим запросом на дозагрузку и начнет отдавать в тот, который ответит, что, мол, да, у меня есть такой файл, я готов принять его фрагмент. У вас же дозагрузка идет не с теми же заголовками, что и старт загрузки? Тестриуйте, в общем.
     
  3. nikola166

    nikola166 Новичок

    С нами с:
    5 фев 2017
    Сообщения:
    3
    Симпатии:
    0
    По частям грузиться через отдельные соединения, запросы из JS POST. А как бы вы посоветовали организовать файловый сервер?
     
  4. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    Я бы посоветовал поставить перед контент-серверами некий сервер-балансировщик, в котором будут храниться записи соответствия запросу такого-то ресурса такому-то файлу. И чтобы nginx стучался на него, а тот сам решал, что да как. Такая архитектура позволит вам безболезненно расширяться, не увеличивая время на обход контент-серверов и поиск файлов.
     
  5. nikola166

    nikola166 Новичок

    С нами с:
    5 фев 2017
    Сообщения:
    3
    Симпатии:
    0
    У меня была такая идея, но не будет ли слишком большое delay переноса файла. Поясню, я вижу такую схему:
    У меня есть сервер Загрузчик файлов, на котором и находится мой PHP скрипт загрузки и сохранения файлов. После того как этот скрипт при загрузке файлов отработал и сохранил файл, я выбираю на какой именно сервер мне этот файл нужно перенести, после этого сохраняю в ДБ полный путь до файла и переношу на нужный сервер. Не будет ли момент такой процесс слишком долгий. Или вы другое имели ввиду?
     
  6. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    Нет, вот так как раз делать не нужно. Нужно получить запрос на загрузку, запросить у контент-балансировщика локальный адрес для загрузки, он выберет сервер, создаст у себя для загружаемого файла запись, указывающую, на каком сервере этот файлик искать, и вернет путь, на который фал надо заливать. То есть сам балансировщик не участвует в загрузке/отдаче файлов вообще. Он просто распределяет их по хранилищам, и сообщает, откуда их можно забрать. В идеале один такой балансир может целый кластер обслуживать.
    --- Добавлено ---
    Взять тот же пикабу какой-нибудь. Одна страница там может содержать картинки с кучи разных контент-серверов. Сомневаюсь, что страницы там хранятся сразу с такими сслыками. Скорее, каждая карттинка вставляется как некий "ATTACH_#ID", который, при сборке страницы, резолвится в адрес на конкретном контент-сервере, а потом кешируется в таком виде. Аналогично - при загрузке. Мы заливаем картинку сразу на контент сервер, и она сразу резолвится в конкретный адрес. Без каких бы то ни было делеев. Контент серверы же работают параллельно и отлично делят нагрузку.

    А ваша схема, с буферной загрузкой, скорее всего ляжет под потоком пользователей, потому что буфер должен будеть через себя прокачивать трафик, предназначенный для нескольких независимых машин. А даже по локалке файлы не прокачиваются между узлами сети мгновенно. Да что там, внутри одной машины между каталогами их без задержки не переместишь.
     
  7. valentinnew

    valentinnew Активный пользователь

    С нами с:
    30 янв 2011
    Сообщения:
    160
    Симпатии:
    35
    Не знаю, как такое возможно - по чатсям загружать? Загрузка файла - это пост запрос. Если он оборвался, то всё, загрузку придется делать заново. Nginx может кэшировать этот файл. Т.е. он со скоростью клиента подгрузает себе, а потом передает с максимальной скоростью апстрима.
    По поводу хранения:
    лучше всего заливать файл на локальный сервер (куда пришел пост запрос), потом отпустить пользователя и обработать файл. Под обработкой я понимаю - залить на один или несколько серверов статики, ужать, повернуть, сконверитровать, обрезать, потом записать в БД то что получилось.

    Так и статику можно вообще на отдельный домен вывести. Хотя с приходом http2 это будет неактуально.
     
    #7 valentinnew, 17 фев 2017
    Последнее редактирование: 17 фев 2017
  8. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    Возможно, если инициатором является не голозадый браузерный запрос, а JS. Как пример: https://habrahabr.ru/company/Techart/blog/100189/
     
  9. valentinnew

    valentinnew Активный пользователь

    С нами с:
    30 янв 2011
    Сообщения:
    160
    Симпатии:
    35
    думаю, если ТС модет настроить балансир, несколько пхп серверов и прочее, то и настроить ограничение на размер загружаемого файла, ктотрый обходят в статье на хабре, тоже сможет. Более того, я не вижу задачу в той статье сложной, а решение необычным.
    я считаю что добавление управления балансиром извне - это внесение дополнительной сложности и связности системы в целом, которая понижает её надежность.
     
  10. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    Я ему про возможность загрузки частями, он мне про размер загружаемого файла... Мне казалось, что очевидно, что, в контексте темы разговора, в статье по ссылке главное - это как раз ответ на вопрос
    А не то, что там у автора настройки хостинга дубовые...

    Был вопрос, был дан ответ. Загружать файл по частям можно. Серией POST-ов. Это может быть полезным, если у клиента не стабильный канал, к примеру, и вероятность успешной отправки файла обратно пропорциональна размеру файла. В таком случае, автономный менеджер на клиенте - очень хорошее решение.
     
  11. valentinnew

    valentinnew Активный пользователь

    С нами с:
    30 янв 2011
    Сообщения:
    160
    Симпатии:
    35
    Нельзя. Это загрузка разных файлов. Ни nginx, ни браузер не поддерживает частичную загрузку файлов по протоколу http. То о чем в статье на хабре - это конкретная задача, которая появилась из-за каких-то нестандартных условий.
    Опять повторю, самым лучшим решением будет обычная загрузка файла с постобработкой.
    Тот же js может контроллировать и визуализировать этот процесс.

    Т.е. что я предлагаю:
    js режет файл на части и отправляет их на сервер при этом показывает полосу прогресса.
    php параллельно принимает эти части и скидывает их в какое-то отдельное хранилище, при этом записывает необходимые данные в БД.
    Когда js видит, что все части успешно загружены, он посылает еще один запрос, который запускает некий процесс (демон), который и собирает все части в единое целое и записывает результат в БД. Все.

    И не надо следить за тем, куда какие запросы отправлялись, не надо для этого ставить какой-то балансировщик. У кода нет зависимости от настроек серверов, получается более ровономерное распределние нагрузки (в случае если части одного файла должны приходить на один сервер, чисто теоретически, очень много запросов может придти на один сервер, при этом другие будут пустовать)
    Накладные расходы на перемещение файлов несущественны по сравнению со временем загрузки файла от пользователя, т.к. чаще всего скорость между сервером и пользователем на много меньше, чем скорость между серверами. Причем последнее контроллируется владельцами сайта.
    Есть реальные практики загрузки файлов на сервер в питере, создании превьюшек и отправки на сервер амазона, при этом время ожидания после непосредственно загрузки было небольшим.

    @Fell-x27 вы все говорите о каких-то несущественных вещах - где это пригодится, кому это нужно, а суть то как раз и сводится к загрузке нескольких файлов и обработкой их всех вместе. Так может на этом и сконцентрируемся? Объективно.
     
  12. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    Взаимоисключающие параграфы...
    Ты уж определись, можно или нельзя :D

    Балансировка не нужна, нужно все запросы на запись гнать на единую машину, чтобы было более равномерное распределение нагрузки? Давно перекос нагрузки на одну ноду стал синонимом равномерного распределения?

    Существенны. Если я залил гигабайт данных, я хочу, чтобы он стал доступен здесь и сейчас, чтобы не ждать потом еще, пока этот гигабайт зальется на левую ноду, при том, что таких как я может быть очень много.

    Не владельцами сайта, а законами физики.

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

    valentinnew Активный пользователь

    С нами с:
    30 янв 2011
    Сообщения:
    160
    Симпатии:
    35
    @Fell-x27 что-то мы о разных вещах говорим. точнее на разных языках.
     
  14. valentinnew

    valentinnew Активный пользователь

    С нами с:
    30 янв 2011
    Сообщения:
    160
    Симпатии:
    35
    протоколом http нельзя.
    а еще я написал что не надо этот балансировщик настраивать особым образом, который все части одного файла гнал на одну ноду.
    Но я имел ввиду про тот контент балансировщик, который вы предложили, определяет на какой сервер грузить части.
    Пирмер 1: один клинет, 10 серверов - все части грузят на один сервер, он загружен, все остальные простаивают.
    Привет 2: много клиентов с мальенькими файлам, и пара - с гиганскими - по вашей схеме будет сервера, которые принимают большие файлы опть же будут загружены непропорционально больше. Более того, на один и тот же сервер могут придти оба больших файла.
    А я хочу чтобы все мои видоефайлы были всегда достепны на моем планшете во сем мире.
    Ширина канала между серверами контроллируется владельцами сайта, ширина канала между пользоватем и сайтом контроллируется условиями, на которые владельцы сайта повлиять не могут.
    Да, с балансировщиком неточность произошла. Нет, схема стандартная - nginx и несколько php серверов.
     
  15. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    Я же скинул ссылку, где прям вот прям прям прям прям прям вот код написан, который это делает.
    А тут не об http ли идет речь? Да даже если не об http, а о каких-нибудь вебсокетах, какая разница? Что там пачка байт, что тут пачка байт.
    Вы договоритесь, сначала, сами с собой уже. В том, что вы говорите, противоречие на противоречии.
     
  16. valentinnew

    valentinnew Активный пользователь

    С нами с:
    30 янв 2011
    Сообщения:
    160
    Симпатии:
    35
    вот скажите, http режет файл? нет
    для него есть разница, передается часть файла или файл целиком? нет
    Так где тут противоречие? Я к тому, что еслиб http мог передавать файл по частям, то это поддерживал бы и nginx и сбор файла в единое целое, скорее всего решалось на уровне его настройки.
    Мне кажется, что мы говорим о разных вещах, вот и недопонимание.
    Я считаю, что принципиально нельзя говорить фронтенду(js'у) на какой конкретно сервер необходимо слать части. Это усложняет и фронтед и бэкэнд. А фронтенд должен брать на себя только отображение.

    Вобщем, думаю, что мы тут достаточно написали, чтобы тс решил как быть)
     
  17. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    При чем тут это...? Что ж так все тяжко идет..
    Недопонимание от того, что вы не понимаете до конца, о чем говорите.
    Это не усложняет ничего. Это на один запрос больше. Фронтенду просто надо получить путь к контент-серверу, готовому принять запрос. Это строчка текста. Да дада, плюс всякие секьюр токены и тд. Это само собой разумеется.
     
  18. valentinnew

    valentinnew Активный пользователь

    С нами с:
    30 янв 2011
    Сообщения:
    160
    Симпатии:
    35
    ну тогда надо в баре посидеть, чтоб пришло взаимное понимание)
     
  19. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА