运行SpringBootApplication PostConstruct和PreDestroy

时间:2017-03-14 06:50:28

标签: java spring docker spring-boot sigkill

我在docker容器中运行spring应用程序时遇到了麻烦(spring和docker在我的环境中都有最新版本)。 我希望为应用程序类AnalysisServiceBootstrap提供健康的生命周期:在创建AnalysisServiceBootstrap之后立即使用方法start()运行初始化代码,并在销毁AnalysisServiceBootstrap之前运行方法stop()(我想在某人时运行stop()代码)停止申请。)

我有以下代码:

package com.pack;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;

@SpringBootApplication
public class AnalysisServiceBootstrap {

    // called OK on docker "start <containerId>"
    @PostConstruct
    public void start() throws Exception {
        // some init code
    }

    // NOT called on "docker stop <containerId>"
    @PreDestroy
    public void stop() {
       // some destroy code
    }

    public static void main(String[] args) {
        SpringApplication.run(AnalysisServiceBootstrap.class, args);
    }
}

出于某种原因,我无法在docker stop上运行方法stop()。 我尝试了stackoverflow和其他资源提供的几种方法,但所有这些方法都不适用于我。

我很乐意拥有适合您的代码(不仅仅是一些时尚建议)。

这是我的几乎所有的docker文件:

FROM *********:6556/service-jvm

ARG SERVICE_JAR_FILE

ENV SERVICE_NAME service
ENV HTTP_PORT 603
ENV HTTPS_PORT 604
ENV SERVICE_JAR /opt/my/project/${SERVICE_JAR_FILE}
EXPOSE ${HTTP_PORT} ${HTTPS_PORT}
COPY ${SERVICE_JAR_FILE} /opt/my/project/${SERVICE_JAR_FILE}

CMD java -Xms1024m -Xmx1024m -dump:"/opt/my/project/dumppath" -javaagent:/opt/my/project/agent.jar -Djav.awt.headless=true -jar ${SERVICE_JAR} 

但是你被邀请在这里发布任何有效的docker文件。

非常感谢。

3 个答案:

答案 0 :(得分:10)

来自文档:

  

码头停止

     

停止一个或多个正在运行的容器   容器内的主要流程将收到<code> cmnd = ['/root/bin/ffmpeg', '-i', videopath] process = subprocess.Popen(cmnd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout, stderr = process.communicate() #This matches regex to get the time in H:M:S format matches = re.search(r"Duration:\s{1}(?P<hours>\d+?):(?P<minutes>\d+?):(?P<seconds>\d+\.\d+?),", stdout, re.DOTALL).groupdict() t_hour = matches['hours'] t_min = matches['minutes'] t_sec = matches['seconds'] t_hour_sec = int(t_hour) * 3600 t_min_sec = int(t_min) * 60 t_s_sec = int(round(float(t_sec))) total_sec = t_hour_sec + t_min_sec + t_s_sec #This matches1 is to get the frame rate of a video matches1 = re.search(r'(\d+) fps', stdout) frame_rate = matches1.group(0) // This will give 20fps frame_rate = matches1.group(1) //It will give 20 </code> ,并在宽限期后SIGTERM

通过执行SIGKILL,你只是在杀死java(Spring)进程。

那么Spring上下文将正确关闭的保证是什么?

在Spring应用程序中处理docker stop的正确方法是添加shutdown hook。

最终代码应如下所示:

SIGTERM

以下问题描述了该过程:

答案 1 :(得分:1)

如此处所述,向应用程序注册一个关闭挂钩 Spring Boot shutdown hook

  

每个SpringApplication都会向JVM注册一个关闭钩子,以确保在退出时正常关闭ApplicationContext。可以使用所有标准的Spring生命周期回调(例如DisposableBean接口或@PreDestroy注释)。

答案 2 :(得分:0)

@PreDestroy或实现DisposableBean的destroy()仅在执行ctrl + c或docker stop <>时执行。但是如果我们执行docker kill <>或直接从intelij IDE停止它,它将不会执行