Приложение Spring Boot как служба демона?

Я новичок, начинаю изучать Spring Boot. Я чувствую, что это действительно полезный и отличный инструмент для легкой разработки Java-приложений.

С другой стороны, я рассматриваю возможность разработки службы Daemon, которая собирает данные/сообщения (сообщения) от Apache Kafka через Kafka Consumer API и выполняет некоторую обработку полученных данных. Все эти процессы, конечно, делаются периодически.

Поэтому я разрабатывал приложение в качестве демона с помощью Apache Commons Daemon. Однако теперь я хочу использовать вместо него Spring Boot.

Возможно ли реализовать такое сервисное приложение через Spring Boot? Если можно, подскажите, как это можно реализовать. Заранее спасибо!


person BG. KIM    schedule 17.03.2016    source источник


Ответы (1)


Я нашел это где-то, поэтому извиняюсь перед первоначальным владельцем, но я создал проект, в который добавил зависимость от spring-boot-loader.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-loader</artifactId>
    <scope>provided</scope>
</dependency>

из-за необходимости расширить класс JarLauncher. Spring boot предоставляет специальную программу запуска, которая изменяет загрузчик класса поведения Java. Класс org.springframework.boot.loader.JarLauncher создает специальный загрузчик классов и запускает приложение.

Поскольку я хотел запустить приложение как оконный сервис, я выбрал Procrun в качестве менеджера сервисов. Для Procrun требуется два метода запуска и остановки или один метод с параметром строкового массива (подробнее см. проект procrun). Поэтому я создал класс Bootsrap, который расширил JarLauncher и реализовал методы, которые нужны Procrun.

public class Bootstrap extends JarLauncher {

private static ClassLoader classLoader = null;
private static Bootstrap bootstrap = null;

protected void launch(String[] args, String mainClass, ClassLoader classLoader, boolean wait)
        throws Exception {
    Runnable runner = createMainMethodRunner(mainClass, args, classLoader);
    Thread runnerThread = new Thread(runner);
    runnerThread.setContextClassLoader(classLoader);
    runnerThread.setName(Thread.currentThread().getName());
    runnerThread.start();
    if (wait == true) {
        runnerThread.join();
    }
}

public static void start (String []args) {
    bootstrap = new Bootstrap ();
    try {
        JarFile.registerUrlProtocolHandler();
        classLoader = bootstrap.createClassLoader(bootstrap.getClassPathArchives());
        bootstrap.launch(args, bootstrap.getMainClass(), classLoader, true);
    }
    catch (Exception ex) {
        ex.printStackTrace();
        System.exit(1);
    }
}

public static void stop (String []args) {
    try {
        if (bootstrap != null) {
            bootstrap.launch(args, bootstrap.getMainClass(), classLoader, true);
            bootstrap = null;
            classLoader = null;
        }
    }
    catch (Exception ex) {
        ex.printStackTrace();
        System.exit(1);
    }
}

public static void main(String[] args) {
    String mode = args != null && args.length > 0 ? args[0] : null;
    if ("start".equals(mode)) {
        Bootstrap.start(args);
    }
    else if ("stop".equals(mode)) {
        Bootstrap.stop(args);
    }
}
}

В классе приложения весенней загрузки я изменил основной метод на:

private static ApplicationContext applicationContext = null;

public static void main(String[] args) {
    String mode = args != null && args.length > 0 ? args[0] : null;

    if (logger.isDebugEnabled()) {
        logger.debug("PID:" + ManagementFactory.getRuntimeMXBean().getName() + 
                     " Application mode:" + mode + " context:" + applicationContext);
    }
    if (applicationContext != null && mode != null && "stop".equals(mode)) {
        System.exit(SpringApplication.exit(applicationContext, new ExitCodeGenerator() {
            @Override
            public int getExitCode() {
                return 0;
            }
        }));
    }
    else {
        SpringApplication app = new SpringApplication(TestProcrunApplication.class);
        applicationContext = app.run(args);
        if (logger.isDebugEnabled()) {
            logger.debug("PID:" + ManagementFactory.getRuntimeMXBean().getName() + 
                         " Application started context:" + applicationContext);
        }
    }
}

Затем я установил службу с помощью prunsrv.exe:

prunsrv.exe //IS//test-procrun --DisplayName="test-procrun" --Description="test-procrun" --Startup=auto --Install=%CD%\prunsrv.exe --Jvm=auto --Classpath=%CD%..\target\test-procrun-0.0.1-SNAPSHOT.jar --StartMode=jvm --StartClass=it.test.procrun.Bootstrap --StartMethod=start --StartParams=start - -StopMode=jvm --StopClass=it.test.procrun.Bootstrap --StopMethod=stop --StopParams=stop --StdOutput=auto --StdError=auto --LogPath=%CD% --LogLevel=Debug

person ismoore999    schedule 17.03.2016
comment
Спасибо за большую помощь! Кстати, мне жаль, что я забыл упомянуть, что искал службу Daemon в среде Linux, особенно в CentOS 7. Не могли бы вы дать мне какой-нибудь совет по этому поводу? - person BG. KIM; 21.03.2016
comment
Думаю, вы получили это от: zazos79. blogspot.com/2015/02/ , hth -adym - person lincolnadym; 21.09.2016
comment
grokonez.com/java-integration/ - person Prashanth Shyamprasad; 15.04.2020