我有一个使用可执行jar文件运行的spring启动应用程序。目前停止服务我们正在杀死这个过程。我看到我们可以使用以下方法正常关闭应用程序。
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 / batch脚本来触发我可以在其中调用ctx.close()
方法的java类?我们正在寻找一个关闭脚本,就像我们从一个独立的tomcat容器(shutdown.bat / shutdown.sh)那样,我们可以将我们的应用程序作为jar文件提供给我们的客户,他们可以通过以下方式启动或停止应用程序:执行这些脚本。 (他们习惯了。)
谢谢, 桑杰
答案 0 :(得分:0)
我认为您可以通过检查命令行参数来检测您正在运行jar作为命令行实用程序,而不是加载整个Spring上下文并启动Web应用程序,只需HTTP访问本地shutdownSpringBoot
使用内置Java HTTP客户端的URL。
答案 1 :(得分:0)
您可以创建一个shell脚本并直接关闭springboot应用程序。只需确保将spring hook注册到spring boot应用程序即可。在关闭钩子中,您可以关闭上下文。您可以查看我的回答here
答案 2 :(得分:0)
我使用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