Spring Boot 2.3.0 如何优雅停机,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
先来一段简单的代码,如下:
@RestControllerpublic class DemoController { @GetMapping("/demo") public String demo() throws InterruptedException { // 模拟业务耗时处理流程 Thread.sleep(20 * 1000L); return "hello"; }}
当我们流量请求到此接口执行业务逻辑的时候,若服务端此时执行关机 (kill),spring boot 默认情况会直接关闭容器(tomcat 等),导致此业务逻辑执行失败。在一些业务场景下:会出现数据不一致的情况,事务逻辑不会回滚。
在最新的 spring boot 2.3 版本,内置此功能,不需要再自行扩展容器线程池来处理, 目前 spring boot 嵌入式支持的 web 服务器(Jetty、Reactor Netty、Tomcat 和 Undertow)以及反应式和基于 Servlet 的 web 应用程序都支持优雅停机功能。
我们来看下如何使用:
当使用server.shutdown=graceful
启用时,在 web 容器关闭时,web 服务器将不再接收新请求,并将等待活动请求完成的缓冲期。
/** * 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、请求服务端接口
2、执行关闭应用
3、服务端接到关闭指令
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 complete2020-05-17 18:28:45.923 INFO 60341 --- [tomcat-shutdown] o.s.b.w.e.tomcat.GracefulShutdown : Graceful shutdown complete
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
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(); }}
容器停机行为取决于具体的 web 容器行为
web 容器名称 | 行为说明 |
---|---|
tomcat 9.0.33+ | 停止接收请求,客户端新请求等待超时。 |
Reactor Netty | 停止接收请求,客户端新请求等待超时。 |
Undertow | 停止接收请求,客户端新请求直接返回 503。 |
关于Spring Boot 2.3.0 如何优雅停机问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/u/3077716/blog/4402151