Spring Boot: разработка приложения с веб- и не-веб-процессами CLI в качестве монолита
Я ищу лучший способ реализовать одномодульный проект Spring Boot, который может работать как несколько процессов (1) обслуживающих REST API или (2) запускающих один из многих процессов CLI.
Подробности:
У нас есть три компонента в упрощенной версии нашего приложения:
- Процесс приема, который запускается как процесс командной строки. Он подключается к внешнему источнику данных, извлекает данные и помещает их в очередь Pulsar.
- Процесс анализа, который также запускается как процесс командной строки. Он потребляет любые данные из очереди Pulsar, выполняет некоторую обработку и сохраняет результаты в базе данных MySQL.
- Веб-приложение REST, которое запускает сервер, прослушивающий порт 8080. Предоставленные API-интерфейсы REST запрашивают данные MySQL и возвращают отчеты на основе уже проанализированных данных.
Вопрос:
- Если я создаю приложение Spring Boot, как мне получить несколько точек входа, чтобы при его запуске я мог сказать, какой из трех процессов я хочу запустить.
- Использование ApplicationRunner не будет работать, поскольку оно запустит веб-приложение + процесс приема + процесс анализа как единый процесс.
- Вариант состоит в том, чтобы написать некоторую логику в основном загрузочном приложении spring как «диспетчер», чтобы он запускал правильный процесс на основе некоторых параметров командной строки. Например: java MyApp — запуск веб-приложения или java MyApp — запуск процесса загрузки.
- Я знаю, что использование нескольких модулей является вариантом, но я думаю, что это добавляет сложности, которых наша небольшая команда хочет избежать, если мы можем, когда мы создаем MVC приложения. Тем более, что я ожидаю, что в окончательной версии приложения будет 20-30 различных процессов для получения данных из разных внешних источников данных. Я хочу запускать каждый из них как отдельные процессы командной строки, даже если каждый из них легкий.
- Я рассматриваю Spring Modulith как способ организации проектов Spring в облегченных модулях, но я ничего не вижу о различных приложениях, которые я могу запускать.
Любые советы по архитектуре будут полезны. Я новичок в Spring Boot, но в остальном я создавал сложные приложения на основе Java более 10 лет; и теперь пытаюсь изучить лучшие практики в мире Spring.
Я ищу лучшие практики по разработке приложения. Мы небольшая команда, у которой есть крайний срок, чтобы быстро создать MVP.
1 ответ
Вы можете сделать так, чтобы ваш код имел три разных «идентификатора», добавив в код логику стробирования на основе некоторого входного фактора, который ваш код использует, чтобы решить, какое удостоверение принять. Вы можете условно запустить веб-сервер на основе этого входного фактора. Вот простой пример, который запускает встроенный веб-сервер Tomcat, только если аргументы командной строки не указаны, и запускает операцию на основе первого аргумента командной строки, если он предоставлен:
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
public static void main(String[] args) {
WebApplicationType appType;
if (args.length > 0)
appType = WebApplicationType.NONE;
else
appType = WebApplicationType.SERVLET;
SpringApplication application = new SpringApplication(DemoApplication.class);
application.setWebApplicationType(appType);
application.run(args);
}
public void run(String... args) throws Exception {
if (args.length > 0) {
if (args[0].equals("operation1")) {
System.out.println("Did operation 1");
}
else if (args[0].equals("operation2")) {
System.out.println("Did operation 2");
}
}
}
}
Это приложение будет работать непрерывно, если не заданы аргументы командной строки, обслуживая любые конечные точки, которые вы определили, и будет выполнять соответствующее приложение, если задан первый аргумент командной строки «операция1» или «операция2», и ничего не будет делать (просто выйдет ) если задан любой другой первый аргумент.
Можно, конечно, поместить код каждой из трех удостоверений в разные модули, но это необязательно. Определенные операции могут либо выполнять какое-либо действие, а затем завершаться, непрерывно выполняться в цикле или запускать поток для обработки того, что делает эта операция. Если вы запустите поток и не сделаете его потоком демона, то основной поток (бегун) может завершиться и выйти, а приложение будет оставаться в живых до тех пор, пока операционный поток продолжает работать.