Spring Boot - запуск запланированных заданий как отдельного процесса - PullRequest
0 голосов
/ 01 марта 2020

У меня есть приложение весенней загрузки, у которого также есть несколько запланированных заданий. Я не вижу никаких функциональных проблем с реализацией. одна из работ выполняется каждую секунду для обновления в реальном времени. Есть и другие задания.

Я подозреваю, что есть проблема с производительностью, особенно когда долго работающий API попадает на контроллер.

// Heavy Job
@Scheduled(fixedRate = 10000)
public void processAlerts(){
}


@Scheduled(fixedDelayString = "${process.events.interval}")
public void triggerTaskReadiness() throws IOException {
    log.info("Trigger event processing job");
}
// Heavy Job to process data from different tables.
@Scheduled(fixedDelayString = "${app.status.interval}")
public void triggerUpdateAppHealth() throws IOException {
    log.info("Trigger application health");
}

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

1 Ответ

1 голос
/ 01 марта 2020

Вопрос слишком общий, ИМО. Все зависит от ваших ресурсов и от того, что именно делает работа.

Spring boot предоставляет механизм планирования общего назначения, но не делает никаких предположений о характере работы.

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

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

С точки зрения начальной загрузки я могу сказать следующее:

  1. Похоже, что работа с базой данных. В этом случае Spring boot поддерживает интеграцию с источниками данных, пул соединений, управление транзакциями, другие API высокого уровня, такие как JPA или даже данные Spring, вы также можете подключить платформы, такие как JOOQ. В итоге, это значительно упрощает фактическую работу с базой данных.

Вы указали Mongodb в теге вопроса - ну, у Spring также есть интеграция mon go db в данных Spring.

Суть в том, что если вы выполняете задание во внешнем процессе, вы вроде как по своему усмотрению (это не значит, что это невозможно сделать, это просто означает, что вы теряете все положительные качества, которые имеет весна). рукава)

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

Относительно API контроллера. Если вы работаете с традиционной пружиной mvc, tomcat имеет пул потоков для обслуживания API, поэтому с точки зрения управления потоками потоки работы не будут конкурировать с потоками контроллера, однако они, скорее всего, будут используйте одно и то же соединение с БД, чтобы оно стало узким местом.

Относительно реализации @Scheduled. По умолчанию будет один поток для обслуживания всех @Scheduled заданий, которых может быть недостаточно.

Вы можете изменить это поведение, создав собственный taskScheduler:

@Bean(destroyMethod = "shutdown")
public Executor taskScheduler() {
    return Executors.newScheduledThreadPool(10); // allocate 10 threads to run @Scheduled jobs
}

Возможно, вам будет интересно прочитать это обсуждение

Spring @Scheduled всегда работает "в границах" одного контекста приложения, управляемого Spring. Так что, если вы решили масштабировать свои экземпляры, каждый экземпляр будет запускать «запланированный» код и выполнять тяжелые задания. Можно использовать Quartz, с которым пружина может быть интегрирована do в кластерный режим, вы можете настроить его так, чтобы каждый раз выбирать один узел и выполнять задание, но, поскольку вы планируете запускать каждую секунду, я сомневаюсь, что кварц будет работать достаточно хорошо.

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

...