欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > spring boot实现不停机更新

spring boot实现不停机更新

2024/10/27 4:11:43 来源:https://blog.csdn.net/u013008898/article/details/142901121  浏览:    关键词:spring boot实现不停机更新

主要实现思路:发布新的应用程序(与原端口不同),启动成功后,将原端口进行优雅关闭,同时将应用程序端口动态切换至原端口

application.yml

server:port: 8000shutdown: graceful

DatapickCliApplication

package com.zy.datapickcli;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServer;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.ServletContextInitializerBeans;
import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.ConfigurableApplicationContext;import java.io.IOException;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.util.Collection;/*** 启动程序** @author javachen*/
@SpringBootApplication
public class DatapickCliApplication
{public static void main(String[] args) {String[] newArgs = args.clone();int defaultPort = 8000;boolean needChangePort = false;if (isPortInUse(defaultPort)) {newArgs = new String[args.length + 1];System.arraycopy(args, 0, newArgs, 0, args.length);newArgs[newArgs.length - 1] = "--server.port=8100";needChangePort = true;}ConfigurableApplicationContext run = SpringApplication.run(DatapickCliApplication.class, newArgs);if (needChangePort) {String command = String.format("lsof -i :%d | grep LISTEN | awk '{print $2}' | xargs kill -2", defaultPort);try {Runtime.getRuntime().exec(new String[]{"sh", "-c", command}).waitFor();while (isPortInUse(defaultPort)) {}ServletWebServerFactory webServerFactory = getWebServerFactory(run);((TomcatServletWebServerFactory) webServerFactory).setPort(defaultPort);WebServer webServer = webServerFactory.getWebServer(invokeSelfInitialize(((ServletWebServerApplicationContext) run)));webServer.start();((ServletWebServerApplicationContext) run).getWebServer().stop();} catch (IOException | InterruptedException ignored) {}}}private static ServletContextInitializer invokeSelfInitialize(ServletWebServerApplicationContext context) {try {Method method = ServletWebServerApplicationContext.class.getDeclaredMethod("getSelfInitializer");method.setAccessible(true);return (ServletContextInitializer) method.invoke(context);} catch (Throwable e) {throw new RuntimeException(e);}}private static boolean isPortInUse(int port) {try (ServerSocket serverSocket = new ServerSocket(port)) {return false;} catch (IOException e) {return true;}}protected static Collection<ServletContextInitializer> getServletContextInitializerBeans(ConfigurableApplicationContext context) {return new ServletContextInitializerBeans(context.getBeanFactory());}private static ServletWebServerFactory getWebServerFactory(ConfigurableApplicationContext context) {String[] beanNames = context.getBeanFactory().getBeanNamesForType(ServletWebServerFactory.class);return context.getBeanFactory().getBean(beanNames[0], ServletWebServerFactory.class);}}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com