2017-03-14 70 views
1

我在運行docker容器中的spring應用程序時遇到了麻煩(spring和docker在我的環境中都有最新版本)。我想爲應用程序類創建健康的生命週期AnalysisServiceBootstrap:使用start()方法運行初始化代碼在創建AnalysisServiceBootstrap之後運行方法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

用'exec'前綴'java'命令以便'CMD exec java'這應該使它成爲應該接收信號的後臺進程。否則它作爲一個正常的bash過程運行,不會收到信號。另請參閱https://www.ctl.io/developers/blog/post/gracefully-stopping-docker-containers/ –

回答

7

從文檔:

搬運工停止

停止一個或多個正在運行的容器 容器內的主要過程將接收SIGTERM,並在寬限期後,SIGKILL

通過執行docker stop你只是在殺死java(Spring)進程。

那麼Spring上下文將會正常關閉的保證是什麼?

在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

Spring Boot會自動註冊一個關閉掛鉤,因此無需執行此操作。但是,當接收到SIGKILL時,沒有任何關機掛鉤會有幫助。 –

+0

這不是工作代碼。你調用Thread的stop()而不是調用我的類的stop。 – sapwood

+0

@ M.Deinum關於'SIGKILL'你是絕對正確的。那麼對此有什麼解決方法? –

0

註冊關機鉤這裏提到的應用程序 Spring Boot shutdown hook

每個SpringApplication將註冊與JVM關閉掛鉤,以確保ApplicationContext需要在退出正常關閉。可以使用所有標準的Spring生命週期回調(如DisposableBean接口或@PreDestroy註釋)。