Манипуляции с передним или фоновым изображением в Rails (Jruby, Torquebox)

У меня загрузка фото с ajax, манипуляции и загрузка на s3 занимают много времени. Я слышал, что лучше выполнять эти задачи в фоновом режиме. Моему приложению нужно подождать, пока фотографии будут загружены. Но если я выберу фоновый способ, мне нужно будет работать с веб-сокетами или повторить ajax, чтобы проверить результат (ссылки на s3) (мне это не нравится). Почему слишком плохо выполнять сложные вычисления прямо в контроллере (передний план)? Теперь я использую Torquebox (Jruby), и, как я понимаю, у него идеальный параллелизм. Значит ли это, что ожидание загрузки на s3 не будет отнимать ресурсы и все будет работать нормально? Пожалуйста, напишите о плюсах и минусах бэк/форграунда в моей ситуации. Благодарю вас!


person makrusak    schedule 23.02.2015    source источник


Ответы (1)


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

По сути, это поток вашей текущей настройки (на переднем плане):

  1. пользователь загружает изображение на ваш сайт, и желаемый контроллер получает запрос.
  2. Ваш контроллер делает синхронный запрос к s3. Это блокирующий запрос.
  3. Ваш контроллер ждет
  4. Ваш контроллер ждет
  5. Ваш контроллер (продолжает) ждать
  6. наконец, (и это не гарантируется) вы получаете ответ от s3, и ваш код продолжает работу и отображает заданное вами представление/json/text/etc.

Очевидно, что шаги 3-5 - очень плохие новости для вашего сервера, и, как я уже говорил ранее, этот рабочий/поток/процесс (в зависимости от вашей инфраструктуры сервера ruby/rails) будет "задерживаться" до тех пор, пока не будет получен ответ от s3 (который потенциально никогда не могло бы произойти).

Вот тот же поток с фоновым заданием с некоторой помощью javascript во внешнем интерфейсе для уведомления:

  1. пользователь загружает изображение на ваш сайт, и желаемый контроллер получает запрос.
  2. Ваш контроллер создает новый поток/процесс, чтобы сделать запрос к s3. Это неблокирующий подход. Вы устанавливаете флаг для записи, которая ссылается на ваш s3 image src, например, complete: false, и ваш код успешно переходит к шагу 3. Теперь ваш новый поток/процесс будет ожидать ответа от s3, и вы установите для флага «завершено» значение true, когда s3 ответит.
  3. Вы визуализируете свое представление/json/текст/и т. д. и по сути освобождаете свой рабочий поток/поток/процесс для этого запроса... хорошие новости!

теперь для забавных передних вещей:

  1. ваш клиент получает ваш ответ, запуская ваш внешний javascript для запуска повторяющейся функции, подобной setInterval, которая «пингует» ваш сервер каждые 3 секунды, где ваш внутренний контроллер проверяет, установлен ли флаг «завершено», который вы установили ранее истинно, и если это так, ответьте/отобразите истинность.
  2. ваш javascript на стороне клиента получает ваш ответ и либо продолжает пинговать (пока вы не укажете, что он должен сдаться), либо прекращает пинговать, потому что ваше приложение ответило верно.

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

  • sidekiq отлично подходит для решения описанных здесь проблем с фоновыми заданиями. Он будет обрабатывать создание нового процесса, в котором вы можете сделать запрос к s3.
  • вот отличный railscast, который поможет вам лучше понять код.
person mkralla11    schedule 23.02.2015
comment
1. Я читал о пулах потоков, и (насколько я понимаю) мое приложение в jruby(java) будет использовать фиксированный пул потоков. Это означает, что большое количество загрузок изображений за один раз может остановить все потоки, когда системные ресурсы закончатся. Я прав? 2. А не могли бы вы ответить, достаточно ли хороши повторяющиеся запросы? Для хорошего клиента мне нужно отправить хотя бы один запрос в секунду. (Являются ли веб-сокеты для этого? Я не буду использовать их в первой версии, но на будущее.) Большое спасибо! - person makrusak; 23.02.2015
comment
@makrusak, вы правы в том, что многие загрузки изображений могут потреблять ваш максимальный размер пула запросов, если вы выполняете синхронную загрузку со своего сервера приложений третьей стороне. Это замедлит работу из-за очереди запросов, как я объяснил выше. Что вы подразумеваете под «повторяющимися запросами»? и «один запрос в секунду»? Веб-сокеты превосходны, если вы предпочитаете получать ответы в режиме реального времени от клиента и от него при выполнении запросов. Однако, как я объяснил, это не решает проблему синхронной загрузки. Веб-сокеты заменят только «пинговые» ajax-запросы. Дайте мне знать, если вам нужна дополнительная помощь. - person mkralla11; 26.02.2015