如何防止Spring Boot守护程序/服务器应用程序立即关闭/关闭?

时间:2015-01-19 03:59:40

标签: java spring spring-boot daemon server

My Spring Boot应用程序不是Web服务器,但它是使用自定义协议的服务器(在本例中使用Camel)。

但Spring Boot在启动后立即停止(优雅地)。我该如何防止这种情况?

我希望应用程序在Ctrl + C或编程时停止。

@CompileStatic
@Configuration
class CamelConfig {

    @Bean
    CamelContextFactoryBean camelContext() {
        final camelContextFactory = new CamelContextFactoryBean()
        camelContextFactory.id = 'camelContext'
        camelContextFactory
    }

}

9 个答案:

答案 0 :(得分:23)

我使用org.springframework.boot.CommandLineRunner + Thread.currentThread().join()找到了解决方案,例如: (注意:下面的代码是Groovy,而不是Java)

package id.ac.itb.lumen.social

import org.slf4j.LoggerFactory
import org.springframework.boot.CommandLineRunner
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication

@SpringBootApplication
class LumenSocialApplication implements CommandLineRunner {

    private static final log = LoggerFactory.getLogger(LumenSocialApplication.class)

    static void main(String[] args) {
        SpringApplication.run LumenSocialApplication, args
    }

    @Override
    void run(String... args) throws Exception {
        log.info('Joining thread, you can press Ctrl+C to shutdown application')
        Thread.currentThread().join()
    }
}

答案 1 :(得分:16)

从Apache Camel 2.17开始,有一个更清晰的答案。引用http://camel.apache.org/spring-boot.html

  

要阻止主线程以便Camel保持运行,请包含spring-boot-starter-web依赖项,或者将camel.springboot.main-run-controller = true添加到application.properties或application.yml文件中

您也需要以下依赖项:

<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-spring-boot-starter</artifactId> <version>2.17.0</version> </dependency>

明确替换<version>2.17.0</version>或使用驼峰BOM导入依赖关系管理信息以保持一致性。

答案 2 :(得分:7)

使用CountDownLatch的示例实现:

@Bean
public CountDownLatch closeLatch() {
    return new CountDownLatch(1);
}

public static void main(String... args) throws InterruptedException {
    ApplicationContext ctx = SpringApplication.run(MyApp.class, args);  

    final CountDownLatch closeLatch = ctx.getBean(CountDownLatch.class);
    Runtime.getRuntime().addShutdownHook(new Thread() {
        @Override
        public void run() {
            closeLatch.countDown();
        }
    });
    closeLatch.await();
}

现在要停止应用程序,您可以从控制台查找进程ID并发出kill命令:

kill <PID>

答案 3 :(得分:4)

Spring Boot将运行应用程序的任务留给实现应用程序的协议。例如,请参阅此guide

  

还需要一些管家对象,如CountDownLatch,以保持主线程的活着......

因此,运行Camel服务的方式是从主Spring Boot应用程序类中将Camel作为standalone application运行。

答案 4 :(得分:1)

现在,这变得更加简单。

只需将camel.springboot.main-run-controller=true添加到您的application.properties

答案 5 :(得分:0)

我的项目是NON WEB Spirng Boot。 我优雅的解决方案是通过CommandLineRunner创建一个守护程序线程。 然后,应用程序不会立即关闭。

 @Bean
    public CommandLineRunner deQueue() {
        return args -> {
            Thread daemonThread;
            consumer.connect(3);
            daemonThread = new Thread(() -> {
                try {
                    consumer.work();
                } catch (InterruptedException e) {
                    logger.info("daemon thread is interrupted", e);
                }
            });
            daemonThread.setDaemon(true);
            daemonThread.start();
        };
    }

答案 6 :(得分:0)

所有线程均已完成,程序将自动关闭。 因此,向@Scheduled注册一个空任务将创建一个循环线程以防止关机。

答案 7 :(得分:-3)

为了在不部署Web应用程序时保持Java进程处于活动状态,请将webEnvironment属性设置为false,如下所示:

 SpringApplication sa = new SpringApplication();
 sa.setWebEnvironment(false); //important
 ApplicationContext ctx = sa.run(ApplicationMain.class, args);

答案 8 :(得分:-4)

对于springboot app连续运行它必须在容器中运行,否则它就像任何java应用程序所有线程完成它完成, 你可以添加

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

它将把它变成webapp,如果不是,你有责任在你的实现中保持它活着