什么是优雅停机

先来一段简单的代码,如下:

@RestController
public class DemoController {
@GetMapping("/demo")
public String demo() throws InterruptedException {
// 模拟业务耗时处理流程
Thread.sleep(20 * 1000L);
return "hello";
}
}

当我们流量请求到此接口执行业务逻辑的时候,若服务端此时执行关机 (kill),spring boot 默认情况会直接关闭容器(tomcat 等),导致此业务逻辑执行失败。在一些业务场景下:会出现数据不一致的情况,事务逻辑不会回滚。

graceful shutdown

在最新的 spring boot 2.3 版本,内置此功能,不需要再自行扩展容器线程池来处理,

目前 spring boot 嵌入式支持的 web 服务器(Jetty、Reactor Netty、Tomcat 和 Undertow)以及反应式和基于 Servlet 的 web 应用程序都支持优雅停机功能。 我们来看下如何使用:

当使用server.shutdown=graceful启用时,在 web 容器关闭时,web 服务器将不再接收新请求,并将等待活动请求完成的缓冲期。

配置体验

此处支持的 shutdown 行为,我们看下 源码枚举如下:
/**
* Configuration for shutting down a {@link WebServer}.
*
* @author Andy Wilkinson
* @since 2.3.0
*/
public enum Shutdown { /**
* 优雅停机 (限期停机)
*
*/
GRACEFUL, /**
* 立即停机
*/
IMMEDIATE; }
缓冲期 timeout-per-shutdown-phase 配置
  • 默认时间为 30S, 意味着最大等待 30S,超时候无论线程任务是否执行完毕都会停机处理,一定要合理合理设置。

效果体验

    1. 请求服务端接口

    1. 执行关闭应用

    1. 服务端接到关闭指令
2020-05-17 18:28:28.940  INFO 60341 --- [extShutdownHook] o.s.b.w.e.tomcat.GracefulShutdown        : Commencing graceful shutdown. Waiting for active requests to complete
2020-05-17 18:28:45.923 INFO 60341 --- [tomcat-shutdown] o.s.b.w.e.tomcat.GracefulShutdown : Graceful shutdown complete
    1. 接口请求执行完成

相关知识

  1. 关于此处执行kill -2 而不是 kill -9
  • kill -2 相当于快捷键 Ctrl + C 会触发 Java 的 ShutdownHook 事件处理(优雅停机或者一些后置处理可参考以下源码)
//ApplicationContext
@Override
public void registerShutdownHook() {
if (this.shutdownHook == null) {
// No shutdown hook registered yet.
this.shutdownHook = new Thread(SHUTDOWN_HOOK_THREAD_NAME) {
@Override
public void run() {
synchronized (startupShutdownMonitor) {
doClose();
}
}
};
Runtime.getRuntime().addShutdownHook(this.shutdownHook);
}
}
  • kill -9,暴力美学强制杀死进程,不会执行 ShutdownHook
  1. 通过 actuate 端点实现优雅停机

POST 请求 /actuator/shutdown 即可执行优雅关机。

源码解析

@Endpoint(id = "shutdown", enableByDefault = false)
public class ShutdownEndpoint implements ApplicationContextAware { @WriteOperation
public Map<String, String> shutdown() {
Thread thread = new Thread(this::performShutdown);
thread.setContextClassLoader(getClass().getClassLoader());
thread.start();
} private void performShutdown() {
try {
Thread.sleep(500L);
}
catch (InterruptedException ex) {
Thread.currentThread().interrupt();
} // 此处close 逻辑和上边 shutdownhook 的处理一样
this.context.close();
}
}
  1. 不同 web 容器优雅停机行为区别

容器停机行为取决于具体的 web 容器行为

web 容器名称 行为说明
tomcat 9.0.33+ 停止接收请求,客户端新请求等待超时。
Reactor Netty 停止接收请求,客户端新请求等待超时。
Undertow 停止接收请求,客户端新请求直接返回 503。

项目推荐: Spring Cloud 、Spring Security OAuth2的RBAC权限管理系统 欢迎关注

Spring Boot 2.3 新特性优雅停机详解的更多相关文章

  1. Spring Boot 系列:最新版优雅停机详解

    爱生活,爱编码,本文已收录架构技术专栏关注这个喜欢分享的地方. 开源项目: 分布式监控(Gitee GVP最有价值开源项目 ):https://gitee.com/sanjiankethree/cub ...

  2. Spring Boot 2(一):Spring Boot 2.0新特性

    Spring Boot 2(一):Spring Boot 2.0新特性 Spring Boot依赖于Spring,而Spring Cloud又依赖于Spring Boot,因此Spring Boot2 ...

  3. spring boot actuator端点高级进阶metris指标详解、git配置详解、自定义扩展详解

    https://www.cnblogs.com/duanxz/p/3508267.html 前言 接着上一篇<Springboot Actuator之一:执行器Actuator入门介绍>a ...

  4. Spring Boot 2.0 新特性和发展方向

    以Java 8 为基准 Spring Boot 2.0 要求Java 版本必须8以上, Java 6 和 7 不再支持. 内嵌容器包结构调整 为了支持reactive使用场景,内嵌的容器包结构被重构了 ...

  5. 【2.0新特性】Spring Boot 2.0新特性

    以Java 8 为基准 Spring Boot 2.0 要求Java 版本必须8以上, Java 6 和 7 不再支持. 内嵌容器包结构调整 为了支持reactive使用场景,内嵌的容器包结构被重构了 ...

  6. Spring Boot实践——Spring Boot 2.0 新特性和发展方向

    出自:https://mp.weixin.qq.com/s/EWmuzsgHueHcSB0WH-3AQw 以Java 8 为基准 Spring Boot 2.0 要求Java 版本必须8以上, Jav ...

  7. Spring Boot 2.0 新特性

    这是一篇总结文章,主要收集 Spring Boot 2.0 相对于 Spring Boot 1.x 的新特性,本章节并不提供实践性质的源代码.在 Spring Boot 系列文章中会持续退出实践章节. ...

  8. 原创 Spring Boot 2.3 新特性分层JAR

    背景 在我们实际生产容器化部署过程中,往往会遇到 Docker 镜像很大,部署发布很慢的情况 影响 docker 镜像大小的因素,主要有以下三个方面: 基础镜像的大小 .尽量选择 aphine 作为基 ...

  9. 『Spring Boot 2.4新特性』减少95%内存占用

    节省 95%的内存占用,减少 80%的启动耗时. GraalVM 是一种高性能的虚拟机,它可以显著的提高程序的性能和运行效率,非常适合微服务.最近比较火的 Java 框架 Quarkus 默认支持 G ...

随机推荐

  1. 为什么说NGK的去中心化预言机越来越受欢迎?

    2020年区块链市场非常火热,从年初的交易所杠杆,到Defi热潮,一波连着一波,风向不断切换,很多人无奈感叹跟不上时代,很多人欢欣雀跃登上了早班车.随着Defi的不断火热,预言机也进入了大众视野.NG ...

  2. OAuth:每次授权暗中保护你的那个“MAN”

    摘要:OAuth是一种授权协议,允许用户在不将账号口令泄露给第三方应用的前提下,使第三方应用可以获得用户在某个web服务上存放资源的访问权限. 背景 在传统模式下,用户的客户端在访问某个web服务提供 ...

  3. jetty的jndi

    jetty的jndi和tomcat的用法 tomcat的jndi是内置的,在web.xml文件里直接默认支持的,所有web项目可以直接使用 <resources> <!-- < ...

  4. [转]ROS 传感器消息及RVIZ可视化Laserscan和PointCloud

    https://blog.csdn.net/yangziluomu/article/details/79576508 https://answers.ros.org/question/60239/ho ...

  5. 蓝绿部署、金丝雀发布(灰度发布)、A/B测试

    本文转载自蓝绿部署.金丝雀发布(灰度发布).A/B测试的准确定义 概述 蓝绿部署.A/B测试.金丝雀发布,以及灰度发布.流量切分等,经常被混为一谈,影响沟通效率. 根本原因是这些名词经常出现,人们耳熟 ...

  6. C# NOPI 项目实战(经典)(可下载项目源码)

    1 -.首先说明下项目目的: 之前我有写过一篇  "NPOI操作EXCEL" 这篇文章主要介绍了如何安装NPOI,以及NPOI具体如何使用,并且用具体实例介绍了excel导入到da ...

  7. dev 控件获得所有的EFDEVGRID

    //获得当前Grid DevExpress.XtraGrid.GridControlNavigator GCN2 = sender as DevExpress.XtraGrid.GridControl ...

  8. redis数据结构和对象一

    1. SDS:简单动态字符串(simple dynamic string) Redis没有直接使用C语言的字符串,而是自己构建了一种名为简单动态字符串类型,并将SDS用作Redis的默认字符串. SD ...

  9. Java并发之ThreadPoolExecutor源码解析(三)

    Worker 先前,笔者讲解到ThreadPoolExecutor.addWorker(Runnable firstTask, boolean core),在这个方法中工作线程可能创建成功,也可能创建 ...

  10. javaScript操作cookie出现同名key

    引文: 网上查找js操作cookie文章发现百度千篇一律全是同样的代码,使用过程中发现一个bug,设置cookie导致出现多个同名key的cookie,官网cookie文档内未提及,下文将标出问题点, ...