Spring Boot 应用程序作为守护进程服务?

问题描述 投票:0回答:2

我是一个刚开始学习 Spring Boot 的新人。我觉得它对于轻松开发 Java 应用程序来说真的很有帮助,很棒的工具。

另一方面,我正在考虑开发一个守护进程服务,它通过 Kafka Consumer API 从 Apache Kafka 收集数据/消息,并对检索到的数据进行一些处理。当然,这整个过程是定期完成的。

因此,我一直使用 Apache Commons Daemon 将应用程序开发为守护进程。然而,我现在想使用 Spring Boot 来代替它。

是否可以通过Spring Boot实现这样的服务应用?如果可能的话,请告诉我如何实施。预先感谢!

spring-boot apache-kafka daemon apache-commons-daemon
2个回答
3
投票

我在某个地方发现了这个,所以向原始所有者道歉,但我创建了一个项目,其中添加了 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);
    }
}
}

在 Spring Boot 应用程序类中,我将 main 方法更改为:

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%.. arget est-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


0
投票

我让它工作了,但它有一些奇怪的行为,就像这些参数一样,我必须添加一个方法 public static void start 和 public static void stop 。我把它们放在我的 Spring boot runner 中。我还必须解压 spring boot jar,将依赖库和类目录添加到类路径中。我必须切换到 amd64 prunsrv.exe,因为另一个是 32 位的,无法与 64 位的 JAVA_HOME jdk 一起使用。安装后,您必须更新或删除该服务才能进行修改。这是我用来修复类路径的更新命令。 prunsrv //US//TestCache2 --Classpath=C: igdataCache igDataCache-web-1.0-SNAPSHOT\BOOT-IN

© www.soinside.com 2019 - 2024. All rights reserved.