как сделать фоновые вычисления в Spring 3.0? - PullRequest
2 голосов
/ 07 февраля 2010

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

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

Я четко знаю требования, но не уверен, какую технологию использовать. JMX, JMS, планировщик задач Spring, интеграция с Spring, mix / match или все.

Это похоже на Как создать фоновый процесс в весеннем веб-приложении? , но не полностью

Редактировать Давайте добавим к этому немного дальше. Существует также возможность сложения этих GPS-координат в большом количестве (через файл CSV) для каждого файла CSV, каждая запись будет обрабатываться в файле (порядок будет для файла «первым пришел - первым обслужен» и для каждой записи). Случай с удалением может быть проще, так как от него ничего не ожидается (но может быть и позже)

Ответы [ 3 ]

3 голосов
/ 07 февраля 2010

Если вам «только» нужно асинхронное выполнение, то подход JMS, предложенный duffymo , безусловно, является хорошим решением (доставка сообщений гарантирована, она отказоустойчива, транзакционна и т. Д.). Однако в случае сбоя сообщения будут откатываться и немедленно доставлено, если вы не настроите Задержка повторной доставки и Лимит повторной доставки . Но хотя некоторые провайдеры JMS действительно предлагают такие функции (например, MQ, WebLogic, JBoss), это не стандартная вещь AFAIK (например, GlassFish OpenMQ не предлагает этого). Вы должны принять это во внимание.

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

3 голосов
/ 07 февраля 2010

Я бы использовал POJO на основе сообщений JMS и Spring. Используйте гарантированную очередь доставки, чтобы гарантировать, что сообщение вернется в очередь в случае сбоя. Укажите очередь ошибок для решения проблем с максимальной повторной попыткой.

2 голосов
/ 07 февраля 2010

Из технологий, которые вы упомянули, JMX не имеет отношения к проблеме, и, хотя JMS, вероятно, будет работать, это, вероятно, будет излишним (количество усилий по настройке может быть значительным, в зависимости от вашей платформы). Кварц также является опцией, хотя сильные стороны Кварца заключаются в планировании по типу cron и кластерном планировании, ни один из которых не кажется вам необходимым.

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

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

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

public class MyTask implements Runnable {
   public void run() {
      while (true) {
         try {
            performWork();
            return;
         } catch (WebServiceFailure f) {
            sleepForFixedPeriod();
         }
      } 
   }
}

Конфигурирование ThreadPoolTaskExecutor - это Spring, для maxPoolSize установлено 1. Затем ваш клиентский код отправляет исполнителям объекты рабочих задач (например, те, что указаны выше).

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

Это не самое элегантное решение, но оно очень простое, понятное и настраиваемое.

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