Springboot 配合 K8s 实现优雅停机


SpringBoot 从2.3.0.RELEASE 开始支持 web 服务器的优雅停机

server:
  # 设置关闭方式为优雅关闭 默认立即
  shutdown: graceful
  
spring:
  lifecycle:
    # 优雅关闭超时时间, 默认30s
    timeout-per-shutdown-phase: 300s
    @GetMapping("startController")
   public String startController(@RequestParam Long dur) {
       LocalDateTime start = LocalDateTime.now();
       while (true) {
           LocalDateTime now = LocalDateTime.now();
           System.out.println("startController当前时间:" + now);
           try {
               TimeUnit.SECONDS.sleep(1L);
           } catch (InterruptedException e) {
               throw new RuntimeException(e);
           }
           long until = start.until(now, ChronoUnit.SECONDS);
           if (until >= dur) {
               break;
           }
       }
       return "cg";
   }

1 java -jar 启动
在这里插入图片描述
2. curl http://192.168.5.156:11111/startController?dur=180 打印180秒日志
在这里插入图片描述
3.kill -2 pid 杀死触发 优雅停机 之后继续打印日志,(kill -9 不会!也不会调用ioc bean的关闭回调)由于我的 timeout-per-shutdown-phase: 300s ,回打印完整180s的日志。即将所有的controller调的方法执行最多300s之后关闭ioc容器。
在这里插入图片描述
3. idea 自带的stop按钮也是kill -2 的优雅杀死。
4. 杀死后会回调所有ioc容器的bean的destroy方法,这个和web的优雅没有关系。在这里插入图片描述
5. 配合k8s的探针,当ctl 发起 kubeclt delete pod 时。k8s发起一个kill -2 命令,服务会立即不接受流量,k8sReadiness探针失败,不再分配流量。
springboot项目若配置了优雅停止,在超时时间内等待所有的controller,即tomcat的线程池的任务全部完成后。k8s持续探测的Liveness探针会在服务完全关闭的时候失败,之后k8s就算成功杀死pod了。
注意controller fork 出来的子线程的任务不会收到web的优雅停机的影响。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐