2017-03-14 2 views
1

docker 컨테이너 (스프링 및 도커 모두 내 환경에 최신 버전 있음)에서 스프링 응용 프로그램을 실행하는 데 문제가 있습니다. 응용 프로그램 클래스 AnalysisServiceBootstrap에 대한 건강한 라이프 사이클을 원합니다 : AnalysisServiceBootstrap을 작성한 후 start() 메소드를 사용하여 초기화 코드를 실행하고 stop() 메소드를 실행하기 전에 AnalysisServiceBootstrap을 삭제하기 전에 (stop() 누군가 응용 프로그램을 중단합니다.) 고정 표시기 정류장에서 실행 나는 방법 정지를 얻을 수없는 어떤 이유로()에 대한SpringBootApplication 실행 PostConstruct 및 PreDestroy

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); 
    } 
} 

:

나는 다음과 같은 코드가 있습니다. stackoverflow 및 기타 리소스를 제공하는 여러 가지 방법을 시도했지만 모두 나를 위해 작동하지 않았다.

일부 보급 제안뿐만 아니라 나와 함께 사용할 수있는 코드를 갖게되어 기쁩니다. 여기

내 거의 정확한 고정 표시기 파일입니다

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} 

하지만 여기에 당신이 어떤 작업 고정 표시기 파일을 게시 초대합니다.

고마워요. 문서에서

+0

'Dockerfile'을 추가하고 컨테이너 (gradle 또는 maven)를 만드는 방법을 보여주세요. –

+0

덧글에 정보를 추가하지 말고 대신 질문을 편집하십시오. –

+0

'java' 명령에'exec' 접두사를 붙이십시오. 그래서'CMD exec java'는 시그널을 받아야하는 백그라운드 프로세스로 만들어야합니다. 그렇지 않으면 신호를 수신하지 않는 정상 bash 프로세스로 실행됩니다. https://www.ctl.io/developers/blog/post/gracefully-stock-docker-containers/ –

답변

7

:

고정 표시기

중지 실행중인 하나 이상의 컨테이너 SIGTERM를받을 용기 내부의 주요 프로세스를 중지하고, 유예 기간 후, SIGKILL

docker stop을 실행하면 java (봄) 프로세스가 종료됩니다.

그렇다면 Spring 컨텍스트가 제대로 종료된다는 보장은 무엇입니까?

스프링 애플리케이션에서 SIGTERM을 올바르게 처리하는 방법은 종료 훅을 추가하는 것입니다.

마지막 코드는 다음과 같아야합니다

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 { 

    @PostConstruct 
    public void start() throws Exception { 
     // some init code 
    } 

    @PreDestroy 
    public void tearDown() { 
     // some destroy code 
    } 

    public static void main(String[] args) { 
     Runtime.getRuntime().addShutdownHook(new Thread() { 
      @Override 
      public void run() { 
       // write here any instructions that should be executed 
       tearDown(); 
      } 
     }); 


     SpringApplication.run(AnalysisServiceBootstrap.class, args); 
    } 
} 

과정은 설명을 다음 질문에 :

+0

스프링 부트는 자동으로 종료 훅을 등록하므로이를 수행 할 필요가 없습니다. 그러나 SIGKILL이 수신되면 셧다운 훅이 도움이되지 않습니다. –

+0

작동하지 않는 코드입니다. 내 클래스의 stop을 호출하는 대신 Thread의 stop()을 호출합니다. – sapwood

+0

@ M.Deinum은'SIGKILL'에 관해서 당신이 절대적으로 옳습니다. 그래서 이것에 대한 해결 방법은 무엇입니까? –

0

가 종료 훅을 등록 여기에 언급 된 응용 프로그램 Spring Boot shutdown hook

각 SpringApplication는 ApplicationContext를 출구에 정상적으로 닫혀 있는지 확인하기 위해 JVM과 종료 훅을 등록합니다. 모든 표준 Spring 라이프 사이클 콜백 (예 : DisposableBean 인터페이스 또는 @PreDestroy 주석)을 사용할 수 있습니다.

관련 문제