将长期运行的服务集成到Spring启动框架中

时间:2018-08-15 21:36:12

标签: java spring spring-boot

我已经实现了将永远运行的kinesis流使用者,我想将其集成到spring框架中以进行监视和正常关闭。但是我发现我无法通过http shutdown请求停止使用者。更具体地说,只有Spring Web App停止了,而使用者没有停止。这是我所做的:

我为spring创建了一个主类,如下所示:

@SpringBootApplication
public class Application {
    public static void main(String[] args)  {
        SpringApplication application = new SpringApplication(Application.class);
        application.addListeners(new ApplicationPidFileWriter("./app.pid"));
        application.run(args);
        System.out.println("I'm Here!!");
    } 
}

在消费者阶层的入口,我在@EventListener(ApplicationReadyEvent.class)方法中添加了startConsumer

@EventListener(ApplicationReadyEvent.class)
public static void startConsumer() throws Exception {
    init();

    ...

    int exitCode = 0;
    try {
        worker.run(); // will run forever
    } catch (Throwable t) {
        System.err.println("Caught throwable while processing data.");
        t.printStackTrace();
        exitCode = 1;
    }
    System.exit(exitCode);
}

使用者在mvn package && java -jar myJar之后成功启动,但是当我使用http shutdown停止程序时,只有spring应用程序停止。消费者仍在运行。

关于如何阻止消费者的任何想法?或更笼统地说,如何将一个长期运行的流程集成到spring框架中?我尝试了非网络选择,但是这阻止了我使用http请求进行监视。

任何建议将不胜感激!

1 个答案:

答案 0 :(得分:0)

重要的一点是,阻塞EventListener中的执行是不正确的。您应该从事件侦听器方法启动一个线程,该线程将为您处理。因此,您需要在单独的线程中调用Worker.run。或者,您可以将事件侦听器标记为@Async

现在的问题是在Spring Boot应用程序停止时正确停止它。

为了能够在春季对关闭事件做出反应,您可以在bean中实现SmartLifecycle

调用stop时,您需要停止Worker。这个answer有一些不错的选择。

确保在工作程序关闭完成后调用传递给Runnable的{​​{1}}。有关更多详细信息,请参见stop javadoc