Отсрочка блокировки Rails-запросов - PullRequest
2 голосов
/ 18 июня 2011

Я нашел вопрос, который объясняет, как работает механизм await () в Play Framework в 1.2. По сути, если вам нужно сделать что-то, что будет блокироваться на измеримый промежуток времени (например, сделать медленный внешний HTTP-запрос), вы можете приостановить ваш запрос и освободить этого работника для работы с другим запросом, пока он блокируется. Я предполагаю, что после завершения операции блокировки ваш запрос перенесен на дальнейшую обработку. Это отличается от планирования работы на фоновом процессоре, а затем для завершения опроса браузера. Я хочу заблокировать браузер, но не рабочий процесс.

Независимо от того, верны ли мои предположения об Play букве, есть ли способ сделать это в приложении на Rails? Я думаю, что можно было бы считать это формой длинного опроса, но я не нашел много советов по этому вопросу, кроме как "использовать узел".

1 Ответ

3 голосов
/ 24 мая 2012

У меня был похожий вопрос о длинных запросах, которые блокируют работников принимать другие запросы.Это проблема со всеми веб-приложениями.Даже Node.js может быть не в состоянии решить проблему, отнимающую слишком много времени у рабочего, или может просто не хватить памяти.

Веб-приложение, над которым я работал, имеет веб-интерфейс, который отправляет запрос в RailsREST API, затем контроллер Rails должен запросить Node REST API, который выполняет трудоемкую задачу, чтобы вернуть некоторые данные.Запрос от Rails к Node.js может занять 2-3 минуты.

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

  1. Frontend делает запрос к Rails API с сгенерированным идентификатором [A] в том же сеансе.(этот идентификатор помогает идентифицировать предыдущий запрос из того же сеанса пользователя).
  2. Rails API передает запрос внешнего интерфейса и идентификатор [A] в службу Node.js
  3. Node.Служба js добавляет это задание в систему очередей (например, RabbitMQ или Redis), сообщение содержит идентификатор [A].(Здесь вы должны подумать, основываясь на своем собственном сценарии, также предполагая, что система будет использовать задание очереди и сохранит результаты)

  4. Если тот же запрос будет отправлен снова, в зависимости от требования,вы можете либо убить текущее задание с тем же идентификатором [A] и запланировать / поставить в очередь последний запрос, либо проигнорировать последний запрос, ожидающий завершения первого, либо другое решение соответствует вашим бизнес-требованиям.

  5. Интерфейс может отправлять интервальный запрос REST, чтобы проверить, завершена ли обработка данных с идентификатором [A] или нет, тогда эти запросы являются легкими и быстрыми.

  6. Как только Node.js завершит работу, вы можете либо воспользоваться системой подписки на сообщения, либо дождаться следующего запроса проверки статуса и вернуть результат во внешний интерфейс.

Вы также можете использоватьбалансировщик нагрузки, например Amazon балансировщик нагрузки, Haproxy .В 37signals есть пост в блоге и видео об использовании Haproxy для выгрузки некоторых долгосрочных запросов, которые не блокируют более короткие.

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

У YouTube есть приятное сообщение для задач с более длинными очередями: «Это занимает больше времени, чем ожидалось. Ваше видео было поставлено в очередь и будет обработано как можно скорее».

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

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

...