Понимание запуска пакетных заданий Spring в веб-контейнере

#java #spring #spring-batch #web-container

#java #spring #spring-batch #веб-контейнер

Вопрос:

Я читал документацию Spring Batch, когда наткнулся на тот факт, что нам пришлось бы использовать другую реализацию интерфейса TaskExecutor (асинхронную версию), если бы нам эффективно приходилось запускать пакетные задания из веб-контейнера.

Я предполагаю, что Http-запрос вызовет пакетное задание. И, насколько я понимаю, когда клиент запускает задание с помощью метода run интерфейса JobLauncher, клиенту приходится ждать, пока объект JobExecution будет возвращен обратно, а поскольку типичное пакетное задание будет выполняться часами подряд, это может быть не очень выполнимо, если задания выполняются синхронно. Теперь AsyncTaskExecutor будет выполнять каждый шаг в отдельных потоках и немедленно вернет объект JobExecution с НЕИЗВЕСТНЫМ статусом.

Во-первых, может кто-нибудь, пожалуйста, объяснить мне, как это работает с точки зрения соединения клиент-сервер? В каждом случае клиент не будет ждать завершения пакета, прежде чем завершить сеанс? Или клиент не будет знать о статусе завершения пакетного задания? Связана ли вся проблема с тем, что соединение должно оставаться до завершения пакета?

В качестве примера, скажем, у клиента есть веб-страница, которая отправляет HTTP-запрос get, который обслуживается методом doget сервлета. Этот метод вызывает метод запуска средства запуска заданий. Этот метод вернет объект JobExecution. И остальная часть истории, как указано выше.

Спасибо, Адитья.

Комментарии:

1. Не могли бы вы привести пример того, как клиент будет вызывать сервер, чтобы прояснить ваш вопрос?

2. Привет, я отредактировал свой вопрос и добавил пример, как вы просили. Надеюсь, теперь все ясно.

Ответ №1:

Это немного зависит от того, что делает ваш сервлет после того, как он вызвал метод run и получил взамен объект JobExecution. Я предположу, что метод doget просто возвращается после вызова run .

Если вы не используете асинхронный исполнитель, вызов метода run в программе запуска заданий будет выполняться синхронно. То есть вызов будет ждать, пока не будет выполнено пакетное задание и не будет возвращен объект JobExecution. С точки зрения подключения HTTP-соединение клиента будет оставаться открытым в течение всего пакетного задания. HTTP-соединение будет закрыто при возврате метода doGet сервлета (или раньше, если на каком-то уровне возникает какой-то тайм-аут, например, брандмауэр или тайм-аут чтения сокета).

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

Комментарии:

1. Спасибо за ваш ответ. Как клиент узнает о состоянии пакетного выполнения в этом случае? Или это невозможно узнать в этом сценарии?

2. Вам нужно будет решить это специальным способом. Типичным способом было бы вернуть клиенту некоторый идентификатор пакета, который затем клиент может использовать для запроса статуса пакета.

3. Я этого не понимаю, AsyncTaskExecutor использует многопоточный подход и, следовательно, должен создавать несколько потоков для выполнения задания. Теперь основной поток (в котором вызывается метод run) завершит работу, подразумевая, что соединение закрыто. Но это означает, что процесс также заканчивается правильно? Это означало бы, что все потоки процесса тоже закончатся? Разве это не так? Как пакетные задания все еще выполняются, когда соединение закрыто? [То есть процесс завершается]. Спасибо за ваши ответы.

4. Если процесс завершится, пакетные задания не будут выполняться, в этом вы правы. Итак, вам нужен какой-то способ поддерживать процесс в рабочем состоянии. Если вы запускаете пакет с помощью сервлета, то вы, вероятно, работаете в веб-контейнере, который не завершится только потому, что соединение с запросом закрыто и поток обработки запросов завершается.

5. @Aditya существуют стандартные способы получения статуса выполнения задания в Spring Batch БЕЗ необходимости какого-либо «пользовательского способа». В зависимости от ваших потребностей вам может просто потребоваться запросить выполнение задания JobExplorer JobOperator или даже JobExecutionDao etc (хотя это должно занимать JobExplorer 99% времени)

Ответ №2:

Выполнение заданий из веб-контейнера

Обычно задания запускаются из командной строки. Однако есть много случаев, когда запуск из an HttpRequest является лучшим вариантом. Многие такие варианты использования включают создание отчетов, выполнение специальных заданий и поддержку веб-приложений. Поскольку пакетное задание по определению выполняется долго, наиболее важной задачей является обеспечение асинхронного запуска задания:

введите описание изображения здесь

Здесь контроллер Spring MVC запускает задание с использованием a JobLauncher , которое было настроено на асинхронный запуск, который немедленно возвращает a JobExecution . Задание, вероятно, все еще будет выполняться, однако это неблокирующее поведение позволяет контроллеру немедленно вернуться, что требуется при обработке HttpRequest .

Пример приведен ниже:

 @Controller
public class JobLauncherController {

    @Autowired
    JobLauncher jobLauncher;

    @Autowired
    Job job;

    @RequestMapping("/jobLauncher.html")
    public void handle() throws Exception{
        jobLauncher.run(job, new JobParameters());
    }
}
  

Источник