[英]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.