Как справиться с поисковой задачей, которая занимает больше времени, чем обычно в Spring 3.0 - PullRequest
0 голосов
/ 04 марта 2011

Я ищу идеи о том, как справиться с задачей, связанной с поиском, которая занимает больше обычного времени (в человеческом выражении более 3 секунд)

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

Контекст проекта - J2EE, Spring и Hibernate (поверх SpringROO)

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

- Фоновые задачи могут быть выполнены с помощью Spring Task executor. Я не уверен, легко ли определить, сколько времени это займет. Вероятно, было бы плохой идеей разрешить одновременное выполнение всех поисковых терминов, поэтому неплохо было бы использовать какое-то объединение.

-Другим вариантом использования фоновых задач является использование JMS. Возможно, это решение с большим контролем (повторные попытки и т. Д.)

-Пружина также приходит на ум

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

Ответы [ 2 ]

1 голос
/ 04 марта 2011

С точки зрения пользователя, я использую AJAX. Веб-страница по умолчанию содержит какой-то индикатор «Занят». Когда AJAX-запрос завершается, индикатор занятости заменяется результатом.

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

Запуск пулов задач в веб-контейнере возможен, но есть некоторые предостережения, особенно о том, как синхронизировать запуск / завершение работы: хотите ли вы, чтобы ваш веб-сервер "зависал" во время завершения работы, когда какой-то поток занят сбором ваших результатов? Также следует учитывать дополнительную нагрузку. Возможно, было бы лучше использовать JMS и перенести нагрузку на второй сервер, выделенный для построения результатов поиска.

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

0 голосов
/ 04 марта 2011

В прошлом я решил эту проблему, выполнив что-то вроде этого:

  • Когда пользователь запускает долгосрочное задание, я открываю всплывающее окно, в котором отображается состояние задания.Статус задачи включает в себя имя и приблизительное время выполнения
  • Эта задача также сохраняется в моем «приложении» (это может храниться в БД, сеансе или контексте приложения), поэтому пользователь может продолжать выполнять другиевещей в моем веб-приложении, имея простой способ вернуться к запущенной задаче.
  • Я сохранил свои задачи в БД, чтобы я мог управлять тем, что происходит при запуске и завершении работы веб-приложения.Для этого необходимо сохранить ход выполнения задачи в БД.
  • Сложной задачей является отображение результатов для пользователя.Если вы используете описанный мной метод, вам нужно будет сохранять результаты в контексте БД, сеанса или приложения.

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

В ответ на комментарий

так что вы используете для фоновых вычислений.Я спрашивал об этом раньше

Я использую java.util.concurrent.Многое из этого зависит от характера вашего приложения.Является ли задача (или шаги в задаче) идемпотентной?Насколько критично, что он работает до конца?Если у вас есть неидемпотентная задача, которая должна выполняться до конца, я бы сказал, что вы обычно должны записывать каждую часть работы, которую вы делаете, и вы должны выполнять эту часть работы в транзакции.Например, если одна из ваших задач состоит в том, чтобы отправить список людей по электронной почте (это определенно не идемпотентно), вы бы отправили электронное письмо в «транзакции» (я использую термин «слегка здесь») и сохранили ваш прогресс после каждой транзакции.полный.

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