Критические части кода в приложении php? - PullRequest
3 голосов
/ 03 апреля 2011

Хорошо, в моей голове это несколько сложно, и я надеюсь, что смогу это объяснить.Если что-то неясно, пожалуйста, прокомментируйте, чтобы я мог уточнить вопрос.

Я хочу обработать загрузку пользовательских файлов на 3-й сервер.

Итак, у нас есть

  • Пользователь
  • веб-сайт (сервер, на котором работает веб-сайт)
  • сервер хранения (который получаетфайл)

Поток должен выглядеть следующим образом:

  1. Веб-сайт запрашивает URL-адрес загрузки со шлюза облачных хранилищ, который указывает непосредственно на конечный сервер хранения (что-то вроде http://serverXY.mystorage.com/upload.php). Вместе с запросом отправляется «целевой путь» (специфичный для сайта и глобально уникальный) и URL-адрес перенаправления.

  2. Сайт генерирует форму загрузки ссерверы хранения загружают URL-адрес в качестве цели, пользователь выбирает файл и нажимает кнопку отправки. Сервер хранения обрабатывает запрос на публикацию, сохраняет файл во временную папку ('/tmp-directory/'.sha1(target-path-fromabove)) и перенаправляет обратно на URL-адрес перенаправления, которыйвеб-сайт был указан. «Путь к цели» также пропущен.

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

  4. Это критические шаги

    • Теперь веб-сайт записывает запись в свою собственную базу данных, ивыдает повторный запрос к API хранилища (подписано, веб-сайт должен пройти проверку подлинности с использованием секретного токена), чтобы
    • копировал файл из своего временного местоположения на сервере хранилища в его окончательное местоположение (это должно быть быстрым, потому что это толькопереименовать)
    • тот же запрос на отдых также вставляет строку базы данных в базу данных сетей хранения вместе с идентификатором веб-сайта как владельца
  5. Все файлы в каталоге tmp включенысервер хранения старше 24 часов автоматически удаляется.

Если пользователь закрывает окно браузера или соединение прерывается, выполнение программы на сервере также прерывается, верно?Выполняются только деструкторы и зарегистрированные функции выключения, верно?

Можно ли как-то сделать эту часть кода "критической", чтобы сервер, если он однажды входит в эту часть кода, выполнял его до конца независимо от того, является ли пользовательпрерывает загрузку страницы или нет?

(Конечно, я знаю, что сбой сервера или ошибка могут прерваться в любое время, но сейчас я беспокоюсь о регулярном потоке)

Один из меня должен был иметь флаг ивременная метка в базе данных веб-сайтов, которая помечает файл как «завершенный» и проверяет хронологию на наличие старых незавершенных файлов и удаляет их из облака хранения, а затем из базы данных веб-сайтов, но я действительно хотел бы избежать этого дополнительного поля и процедуры.

Я хочу, чтобы API хранилища был очень универсальным и использовал его во многих других будущих проектах.

Я посмотрел на хранилище Google для разработчиков и Amazon s3.

Ониесть такая же проблема и даже хуже.В Amazon S3 вы можете «подписать» свой почтовый запрос.Таким образом, файл загружается пользователем под вашим руководством и сохраняется и сохраняется напрямую, и вы должны оплатить его.Если соединение прерывается и пользователь никогда не возвращается на ваш сайт, вы даже не знаете об этом.Таким образом, вы должны хранить все загружаемые вами URL-адреса, подписывать их, проверять их в cronjob и удалять все, что не «достигло места назначения».

Какие-либо идеи или рекомендации для этой проблемы?

Ответы [ 2 ]

1 голос
/ 04 апреля 2011

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

Я вижу два варианта для обеспечения того, чтобыкритические шаги выполняются полностью:

  1. Убедитесь, что PHP игнорирует состояние подключения и выполняет сценарии до конца, используя ignore_user_abort () .
  2. Запустить некоторыеВнутренний процесс, который выполняет критические операции отдельно от пользовательских сценариев.Это может быть так же просто, как перенести задание в очередь at, если вы используете сервер * NIX ( man at для более подробной информации), или так же сложно, как иметь выделенного демона управления очередью, очень похоже наодин из предложенных LrdCasimir.

У всех подобных проблем, с которыми я сталкивался, были довольно трудоемкие процессы, связанные с их работой, поэтому я всегда использовал вариант 2, чтобы быстро реагировать набраузер, и освободить веб-сервер.Вариант 1 прост в реализации, но вариант 2 в конечном итоге более отказоустойчив, так как обновления будут оставаться в очереди до тех пор, пока они не будут успешно переданы на сервер хранения.

Обработка соединения На странице руководства по PHP содержится много хорошего о том, что происходит во время HTTP-соединения.

0 голосов
/ 04 апреля 2011

Я не уверен, что назвал бы это «лучшей практикой», но несколько идей о общем подходе к решению такого рода проблем. Один из них - разрешить асинхронную транзакцию запроса REST к серверу хранения либо с помощью демонизированного процесса, который прослушивает входящие запросы (либо просматривая файл на предмет изменений, либо сокетом, общей памятью, базой данных и т. Д.). Я думаю, что это лучше всего подходит для IPC в вашей среде) или очень часто выполняемой задачи cron, которая собирает и доставляет файлы. Преимущества этого состоят в том, что вы можете быстро отправить сообщение пользователю, который загрузил файл, в то время как фоновый процесс может попытаться, попробуйте еще раз, если есть проблема с подключением к службе REST. Вы можете даже пойти так далеко, что произойдет опрос AJAX, чтобы пользователь мог получить хорошее сообщение JS, отображаемое после завершения процесса REST.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...