zoukankan      html  css  js  c++  java
  • spring cloud shutdown graceful 优雅停机

    spring cloud shutdown graceful 优雅停机

    当一个服务启动后,会注册到eureka中,其他的服务也可以从eureka获取到新注册的服务。但当我们要停止一个服务的时候,如果直接kill -9 pid,未免有些太过暴力。
    

    直接杀进程有什么问题

    eureka要经过一段时间才会把已经挂掉的服务踢出,其他的服务上也还会保留住这个服务一段时间,他们都认为该服务可用。eureka的管理界面中还可以看到该服务,其他服务则还保留这个服务副本一段时间。这时候,如果发起一个请求,就会发生错误,服务不存在或降级。
    

    解决办法

    spring cloud中,提供了shutdown端点,可以实现优雅停机。eureka可以马上把这个服务剔除,其他的服务中保留的这个服务也将被马上踢出。
    

    pom.xml增加依赖

    <dependencies>
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    

    application.properties增加配置

    # 启用shutdown
    endpoints.shutdown.enabled=true
    
    # 禁用密码验证
    endpoints.shutdown.sensitive=false
    

    服务启动后,可以通过linux的curl命令发送POST请求的方式优雅的停止服务。

    curl -X POST host:port/shutdown
    

    如果配置了management.context-path=/manage,则命令变为:

    curl -X POST host:port/manage/shutdown
    

    额外的拓展

    如果调用了curl -X POST host:port/shutdown命令后,还想做一些别的操作,可以在主类中增加监听。
    代码如下:

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.cloud.netflix.feign.EnableFeignClients;
    import org.springframework.context.annotation.Bean;
    
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    import javax.validation.constraints.NotNull;
    
    @SpringBootApplication
    @EnableFeignClients
    @EnableDiscoveryClient
    public class Application {
    
    	public static void main(String[] args) {
    		SpringApplication.run(Application.class, args);
    	}
    	@NotNull
    	@Bean
    	ServletListenerRegistrationBean<ServletContextListener> myServletListener() {
    		ServletListenerRegistrationBean<ServletContextListener> srb =
    				new ServletListenerRegistrationBean<>();
    		srb.setListener(new ExampleServletContextListener());
    		return srb;
    	}
    
    
    	public class ExampleServletContextListener implements ServletContextListener {
    		@Override
    		public void contextInitialized(
    				ServletContextEvent sce) {
    			// Context Initialised
    		}
    
    		@Override
    		public void contextDestroyed(
    				ServletContextEvent sce) {
    			// Here - what you want to do that context shutdown 	
    			System.out.println("==============调用了shutdown后输出==================");
    		}
    	}
    }
    

    参考:

    https://blog.csdn.net/qq276726581/article/details/55520762
    https://blog.csdn.net/chinrui/article/details/78685032
    https://stackoverflow.com/questions/26678208/spring-boot-shutdown-hook/48181392#48181392

  • 相关阅读:
    协程
    多进程
    多线程
    模块进阶
    内建函数
    内建属性
    属性property
    私有化
    深拷贝、浅拷贝
    ==、is
  • 原文地址:https://www.cnblogs.com/liangzs/p/8952378.html
Copyright © 2011-2022 走看看