Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > Выполнение долговременных оперций


Автор: startpoint 3.10.2012, 14:13
Суть проблемы в следующем. Пользователь загружает через веб-интерфейс файлы. Большие. После загрузки, веб-интерфейс ему отвечает "ок, файл загрузился". Однако, после загрузки над файлом нужно выполнить ряд операций. А основная часть этих оперций - консольные приложения. И вот я никак не могу придумать, как же мне всё это делать. Придумал 3 варианта, не знаю что ещё можно, подскажите.
1. Подумал, может использовать какой сервер очередей, типа Apache ActiveMQ, но потом понял, что он мне не подходит, т.к. для такой архитектуры нужен как отправитель, так и получатель. Причём получатель это какой то уже существующий в системе (или на удалённой системе) процесс, а у меня никакого получателя нет. Мне бы его наоборот, создавать каждый раз, по факту загрузки файла.
2. Jenkins. Создать параметризированный job и через REST API вызывать сборку. Отличное решение на мой взляд, но не совсем полноценное. После того, как над файлом будут выполнены все манипуляции, нужно в БД внести соответствующую запись об этом. А увы, всё что будет делать jenkins выполняется не в контексте моего приложения. А в приложении коннект к БД... Этот недостаток присущ и первому варианту.
3. Обрабатывать файл в отдельном потоке на Tomcat'е. Получается что вроде всё нормально - и асинхронно - клиент получил сообщение что файл загружен и в контексте приложения. Только вот я с потоками не особо дружу... К тому же, насколько я знаю, каждый web-сервер может поддерживать определённое количество одновременных соединений, создавая на каждый свой отдельный воркер. Как только запрос отрабатывается, воркер освобождается/убивается. Так вот, если в процессе обработки запроса я уйду в фон, отвалится воркер как положено или нет ? А вообще на первый вгляд это самое разумное и простое решение.
Вообщем нужен совет. Как делаете это вы ?
Я, когда писал на PHP подобные вещи, то в качестве очереди использовал таблицу БД, которую по крону периодически мониторил PHP-скрипт. Ща вот хочется что нибудь по умнее придумать. Так сказать enterprise решение smile

Автор: Ares4322 6.10.2012, 21:20
То есть последовательность действий такая:
  • пришел файл по http
  • приняли
  • передали какому-то сервису
  • сервис обработал
  • получили ответ от сервиса, что все ОК
  • отправили ответ пользователю
Так?

И еще несколько вопросов:
[*]сервисы на той же машине или они раскиданы по сети?
[*]есть ли исходники или jar-ники сервисов?
[*]обработка файлов много времени и вычислительных ресурсов занимает?

Автор: startpoint 10.10.2012, 19:11
Вообщем то я уже всё сделал, как написал в третьем варианте. Т.е. запускаю обработку файла в отдельном потоке, а пользователю говорю ок и он не ждёт, пока файл обработается. Есть косяк, правда, в том, что когда сервак отстанавливаешь, то те вызовы exec до которых ещё не дошло, не выполняются естественно. Вот так примерно выглядит код:
Код

...
// в коде экшена
// file - это ссылка на только что загруженный пользовательский файл
new ReferenceProcessor()
    .setReference(file)
    .start();
...

Код

public class ReferenceProcessor extends Thread {
    public void run() {
        Runtime runtime = Runtime.getRuntime();
        Process process = runtime.exec("first_command --some params " + _file.getPath);
        Process process = runtime.exec("second_command --some params " + _file.getPath);
        Process process = runtime.exec("third_command --some params " + _file.getPath);
    }
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)