簡體   English   中英

從Shell腳本正常關閉Spring Boot應用程序

[英]Gracefully Shutdown Spring Boot Application from Shell Script

我有一個使用可執行jar文件運行的spring boot應用程序。 目前,要停止服務,我們只是取消進程。 我看到我們可以使用以下方法正常關閉應用程序。

ApplicationContext ctx = SpringApplication.run(Application.class, args);

然后在代碼中的某個地方可以調用ctx.close()也可以使用以下靜態方法。

SpringApplication.exit(ApplicationContext, ExitCodeGenerator)

目前它對我們有效,但是實際上我們在控制器內部調用了ctx.close()方法,如下所示。

@RequestMapping("/shutdownSpringBoot")
public void shutdownApplication() {
    MyApplication.ctx.close(); // I'm saving the context returned by spring boot in a static variable inside my main class
}

當我們通過http命中此控制器方法時,該應用程序將正常關閉。 但是我們不想這樣做。 是否可以編寫shell /批處理腳本來觸發我可以在其中調用ctx.close()方法的java類? 我們正在尋找一種關閉腳本,例如從獨立的tomcat容器(shutdown.bat / shutdown.sh)中獲取的腳本,以便我們將應用程序作為jar文件提供給客戶,讓他們可以通過以下方式啟動或停止該應用程序:執行這些腳本。 (他們習慣了)。

謝謝,桑傑

我認為您可以通過檢查命令行參數來簡單地檢測到您正在將jar作為命令行實用程序運行,而不是加載整個Spring上下文並啟動Web應用程序,只需使用內置Java HTTP通過HTTP訪問本地shutdownSpringBoot URL客戶。

您可以創建一個shell腳本並直接關閉springboot應用程序。 只要確保您將關閉鈎子注冊到您的spring boot應用程序即可。 在關閉掛鈎中,您可以關閉上下文。 你可以在這里查看我的答案

我使用PID文件編寫器來編寫文件,並將Jar和Pid存儲在與應用程序名稱相同名稱的文件夾中,並且shell腳本在開始和結束時也具有相同名稱。

主班

@SpringBootApplication
public class MyApplication {

    public static final void main(String[] args) {
        SpringApplicationBuilder app = new SpringApplicationBuilder(MyApplication.class);
        app.build().addListeners(new ApplicationPidFileWriter());
        app.run();
    }
}

YML文件

spring.pid.fail-on-write-error: true
spring.pid.file: /server-path-with-folder-as-app-name-for-ID/appName/appName.pid

這是啟動腳本(start-appname.sh):

shellScriptFileName=$(basename -- "$0")
shellScriptFileNameWithoutExt="${shellScriptFileName%.*}"
appName=${shellScriptFileNameWithoutExt:6}

PROCESS=$1
PIDS=`ps aux |grep [j]ava.*$appName.*jar | awk {'print $2'}`
if [ -z "$PIDS" ]; then
  echo "No instances of $appName is running..." 1>&2
else
  for PID in $PIDS; do
    echo "Waiting for the process($PID) to finish on it's own for 3 mins..."
    sleep 3m
    echo "FATAL:Killing $appName with PID:$PID."
    kill -9 $PID
  done
fi

# Preparing the java home path for execution
JAVA_EXEC='/usr/bin/java'

# Java Executable - Jar Path Obtained from latest file in directory
JAVA_APP=$(ls -t /server-path-with-folder-as-app-name/$appName/$appName*.jar | head -n1)

# JVM Parameters and Spring boot initialization parameters
JVM_PARAM="-Xms512m -Xmx1024m -Dspring.profiles.active=sit -Dcom.webmethods.jms.clientIDSharing=true"

# To execute the application.
FINAL_EXEC="$JAVA_EXEC $JVM_PARAM -jar $JAVA_APP"

# Making executable command using tilde symbol and running completely detached from terminal
`nohup $FINAL_EXEC  </dev/null >/dev/null 2>&1 &`

echo "$appName has been started successfully."

這是停止腳本(stop-appname.sh):

shellScriptFileName=$(basename -- "$0")
shellScriptFileNameWithoutExt="${shellScriptFileName%.*}"
appName=${shellScriptFileNameWithoutExt:5}

# Script to stop the application
PID_PATH="server-path-with-folder-as-app-name-for-PID/$appName/$appName.pid"

if [ ! -f "$PID_PATH" ]; then
   echo "Process Id FilePath($PID_PATH) Not found"
else
pid=`cat $PID_PATH`
    if [ ! -e /proc/$pid -a /proc/$pid/exe ]; then
        echo "$appName was not running.";
    else
       kill $pid;
       echo "Gracefully stopping $appName with PID:$pid..."
    fi
fi

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM