• springboot shutdown(停机)


    springboot shutdown(停机)

    工作中还没有使用过springboot搭建分布式服务。只是通过springboot搭建了一个简单的web工程,跑一些定时任务。所以不清楚springboot集群是如何部署和启停应用的。因为某些原因,工作中不能直接使用springboot打包成jar形式发布。最终决定自己写打包脚本,打包zip(tar.gz),并编写启动和停止脚本。(见文章《springboot打包成zip部署,并实现优雅停机》《springboot 启动脚本优化》

    问题

    那篇文章中通过springboot提供的应用监控插件,可以实现停机服务。但是有个问题,停机请求的url是写在stop.sh脚本的。如果应用部署的的配置调整了端口号,这样stop.sh脚本也要调整。现在因为单机部署还是没有什么问题,后面如果开始集群部署,肯定会引起很多麻烦。

    思路

    这里就想到了tomcat的启动和停止原理。

    tomcat

    tomcat启动时读取server.xml配置,同时监听一个端口,用于接收停机指令,一般默认是8005。当我们执行shutdown.sh时,执行同样的代码,但是会传入shutdown的参数,同样读取server.xml配置,根据配置的端口,发送shutdown指令,这样启动的服务就收到了停机指令,就开始停机操作。通过启动和停机都读取同一份配置文件,避免启动和停机需要维护两份配置的问题。

    springboot

    鉴于tomcat的启停原理,如果我停机的java代码中也能读取springboot的配置文件,获取应用的端口信息,再根据这个端口信息去发送停机请求。这样就可以避免修改stop.sh脚本。所以最重要的是如何自己读取springboot的配置文件。

    改造

    因为重点是读取springboot的配置,项目采用的是yml形式配置,一开始想到的是自己解析yml,但是出现了问题。项目采用application-dev.yml、application-test.yml等区分不同环境配置。我需要先解析application.yml配置,再根据spring.profiles.active配置读取对应配置文件。这样是不是太麻烦了呢?这个工作springboot不是已经做了一遍了吗?我是不是可以直接拿springboot解析配置文件的代码直接使用呢?

    带着这样的疑问,我决定寻找一些springboot读取配置文件的原理。最后找到了这篇文章Spring Boot源码分析-配置文件加载。文中用的springboot版本是Spring Boot 2.1.0.RELEASE。我用的是Spring Boot 2.0.4.RELEASE,刚好可以借鉴一下。

    具体springboot如何读取配置文件,文章中已经写的很清楚了。这里就不复述了。直接贴一下改造后的Shutdown类。

    import org.apache.http.HttpResponse;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.util.EntityUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.context.config.ConfigFileApplicationListener;
    import org.springframework.core.env.ConfigurableEnvironment;
    import org.springframework.core.env.StandardEnvironment;
    import org.springframework.core.io.DefaultResourceLoader;
    import org.springframework.util.StringUtils;
    
    import java.io.IOException;
    
    /**
     * 应用关闭入口
     *
     * @author dingzg
     */
    public class Shutdown extends ConfigFileApplicationListener {
    
        private static final Logger log = LoggerFactory.getLogger(Shutdown.class);
    
        public static void main(String[] args) {
            String url = "http://127.0.0.1:%s/actuator/shutdown";
            Shutdown shutdown = new Shutdown();
            ConfigurableEnvironment environment = shutdown.load();
            String port = environment.getProperty("management.server.port");
            if (StringUtils.isEmpty(port)) {
                port = environment.getProperty("server.port");
            }
            url = String.format(url, port);
            log.info("shutdown url = {}", url);
            HttpClient httpClient = HttpClients.createDefault();
            HttpPost httpPost = new HttpPost(url);
            try {
                HttpResponse httpResponse = httpClient.execute(httpPost);
                String strResult = EntityUtils.toString(httpResponse.getEntity());
                log.info("response = {}", strResult);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 读取springboot配置信息
         * @return
         */
        public ConfigurableEnvironment load() {
            ConfigurableEnvironment environment = new StandardEnvironment();
            super.addPropertySources(environment, new DefaultResourceLoader());
            return environment;
        }
    }
    
  • 相关阅读:
    vue学习简单入门
    Python3基础学习
    MySQL数据库索引详解
    使用nginx部署多个前端项目
    基于SpringBoot2.x和tkMapper快速搭建微服务项目脚手架工程
    安装篇-Linux安装maven3.5.2
    安装篇-安装maven3.6.1
    安装篇-安装Idea2019.3.3
    安装篇-jdk1.8安装
    【错误解决】Intellj(IDEA) warning no artifacts configured
  • 原文地址:https://www.cnblogs.com/jimmyfan/p/13186047.html
Copyright © 2020-2023  润新知