电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

詳解Spring Boot最新版優雅停機的方法

瀏覽:128日期:2023-08-08 16:33:34

什么是優雅停機先來一段簡單的代碼,如下:

@RestControllerpublic class DemoController { @GetMapping('/demo') public String demo() throws InterruptedException { // 模擬業務耗時處理流程 Thread.sleep(20 * 1000L); return 'hello'; }}

當我們流量請求到此接口執行業務邏輯的時候,若服務端此時執行關機 (kill),spring boot 默認情況會直接關閉容器(tomcat 等),導致此業務邏輯執行失敗。在一些業務場景下:會出現數據不一致的情況,事務邏輯不會回滾。

詳解Spring Boot最新版優雅停機的方法

開源項目:

分布式監控(Gitee GVP最有價值開源項目 ):https://gitee.com/sanjiankethree/cubic

攝像頭視頻流采集:https://gitee.com/sanjiankethree/cubic-video

優雅停機

目前Spring Boot已經發展到了2.3.4.RELEASE,伴隨著2.3版本的到來,優雅停機機制也更加完善了。

目前版本的Spring Boot 優雅停機支持Jetty, Reactor Netty, Tomcat和 Undertow 以及反應式和基于 Servlet 的 web 應用程序都支持優雅停機功能。

優雅停機的目的:

如果沒有優雅停機,服務器此時直接直接關閉(kill -9),那么就會導致當前正在容器內運行的業務直接失敗,在某些特殊的場景下產生臟數據。

增加了優雅停機配置后:

在服務器執行關閉(kill -2)時,會預留一點時間使容器內部業務線程執行完畢,此時容器也不允許新的請求進入。新請求的處理方式跟web服務器有關,Reactor Netty、 Tomcat將停止接入請求,Undertow的處理方式是返回503.

新版配置

YAML配置

新版本配置非常簡單,server.shutdown=graceful 就搞定了(注意,優雅停機配置需要配合Tomcat 9.0.33(含)以上版本)

server: port: 6080 shutdown: graceful #開啟優雅停機spring: lifecycle: timeout-per-shutdown-phase: 20s #設置緩沖時間 默認30s

在設置了緩沖參數timeout-per-shutdown-phase 后,在規定時間內如果線程無法執行完畢則會被強制停機。

下面我們來看下停機時,加了優雅停日志和不加的區別:

//未加優雅停機配置Disconnected from the target VM, address: ’127.0.0.1:49754’, transport: ’socket’Process finished with exit code 130 (interrupted by signal 2: SIGINT)

加了優雅停機配置后,可明顯發現的日志 Waiting for active requests to cpmplete,此時容器將在ShutdownHook執行完畢后停止。

詳解Spring Boot最新版優雅停機的方法

關閉方式

1、 一定不要使用kill -9 操作,使用kill -2 來關閉容器。這樣才會觸發java內部ShutdownHook操作,kill -9不會觸發ShutdownHook。

2、可以使用端點監控 POST 請求 /actuator/shutdown 來執行優雅關機。

添加ShutdownHook

通過上面的日志我們發現Druid執行了自己的ShutdownHook,那么我們也來添加下ShutdownHook,有幾種簡單的方式:

1、實現DisposableBean接口,實現destroy方法

@Slf4j@Servicepublic class DefaultDataStore implements DisposableBean { private final ExecutorService executorService = new ThreadPoolExecutor(OSUtil.getAvailableProcessors(), OSUtil.getAvailableProcessors() + 1, 1, TimeUnit.MINUTES, new ArrayBlockingQueue<>(200), new DefaultThreadFactory('UploadVideo')); @Override public void destroy() throws Exception { log.info('準備優雅停止應用使用 DisposableBean'); executorService.shutdown(); }}

2、使用@PreDestroy注解

@Slf4j@Servicepublic class DefaultDataStore { private final ExecutorService executorService = new ThreadPoolExecutor(OSUtil.getAvailableProcessors(), OSUtil.getAvailableProcessors() + 1, 1, TimeUnit.MINUTES, new ArrayBlockingQueue<>(200), new DefaultThreadFactory('UploadVideo')); @PreDestroy public void shutdown() { log.info('準備優雅停止應用 @PreDestroy'); executorService.shutdown(); }}

這里注意,@PreDestroy 比 DisposableBean 先執行

關閉原理

1、使用kill pid關閉,源碼很簡單,大家可以看下GracefulShutdown

private void doShutdown(GracefulShutdownCallback callback) {List<Connector> connectors = getConnectors();connectors.forEach(this::close);try {for (Container host : this.tomcat.getEngine().findChildren()) {for (Container context : host.findChildren()) {while (isActive(context)) {if (this.aborted) {logger.info('Graceful shutdown aborted with one or more requests still active');callback.shutdownComplete(GracefulShutdownResult.REQUESTS_ACTIVE);return;}Thread.sleep(50);}}}}catch (InterruptedException ex) {Thread.currentThread().interrupt();}logger.info('Graceful shutdown complete');callback.shutdownComplete(GracefulShutdownResult.IDLE);}

2、使用端點監控 POST 請求 /actuator/shutdown關閉

因為actuator 都使用了SPI的擴展方式,所以我們看下AutoConfiguration,可以看到關鍵點就是ShutdownEndpoint

@Configuration( proxyBeanMethods = false)@ConditionalOnAvailableEndpoint( endpoint = ShutdownEndpoint.class)public class ShutdownEndpointAutoConfiguration { public ShutdownEndpointAutoConfiguration() { } @Bean( destroyMethod = '' ) @ConditionalOnMissingBean public ShutdownEndpoint shutdownEndpoint() { return new ShutdownEndpoint(); }}

ShutdownEndpoint,為了節省篇幅只留了一點重要的

@Endpoint( id = 'shutdown', enableByDefault = false)public class ShutdownEndpoint implements ApplicationContextAware { @WriteOperation public Map<String, String> shutdown() { if (this.context == null) { return NO_CONTEXT_MESSAGE; } else { boolean var6 = false; Map var1; try { var6 = true; var1 = SHUTDOWN_MESSAGE; var6 = false; } finally { if (var6) { Thread thread = new Thread(this::performShutdown); thread.setContextClassLoader(this.getClass().getClassLoader()); thread.start(); } } Thread thread = new Thread(this::performShutdown); thread.setContextClassLoader(this.getClass().getClassLoader()); thread.start(); return var1; } } private void performShutdown() { try { Thread.sleep(500L); } catch (InterruptedException var2) { Thread.currentThread().interrupt(); } this.context.close(); //這里才是核心 }}

在調用了 this.context.close() ,其實就是AbstractApplicationContext 的close() 方法 (重點是其中的doClose())

/** * Close this application context, destroying all beans in its bean factory. * <p>Delegates to {@code doClose()} for the actual closing procedure. * Also removes a JVM shutdown hook, if registered, as it’s not needed anymore. * @see #doClose() * @see #registerShutdownHook() */@Overridepublic void close() {synchronized (this.startupShutdownMonitor) {doClose(); //重點:銷毀bean 并執行jvm shutdown hook// If we registered a JVM shutdown hook, we don’t need it anymore now:// We’ve already explicitly closed the context.if (this.shutdownHook != null) {try {Runtime.getRuntime().removeShutdownHook(this.shutdownHook);}catch (IllegalStateException ex) {// ignore - VM is already shutting down}}}}

后記

到這里,關于單機版本的Spring Boot優雅停機就說完了。為什么說單機?因為大家也能發現,在關閉時,其實只是保證了服務端內部線程執行完畢,調用方的狀態是沒關注的。

不論是Dubbo還是Cloud 的分布式服務框架,需要關注的是怎么能在服務停止前,先將提供者在注冊中心進行反注冊,然后在停止服務提供者,這樣才能保證業務系統不會產生各種503、timeout等現象。

好在當前Spring Boot 結合Kubernetes已經幫我們搞定了這一點,也就是Spring Boot 2.3版本新功能Liveness(存活狀態) 和Readiness(就緒狀態)

簡單的提下這兩個狀態:

Liveness(存活狀態):Liveness 狀態來查看內部情況可以理解為health check,如果Liveness失敗就就意味著應用處于故障狀態并且目前無法恢復,這種情況就重啟吧。此時Kubernetes如果存活探測失敗將殺死Container。 Readiness(就緒狀態):用來告訴應用是否已經準備好接受客戶端請求,如果Readiness未就緒那么k8s就不能路由流量過來。

到此這篇關于Spring Boot最新版優雅停機的文章就介紹到這了,更多相關Spring Boot優雅停機內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Spring
相關文章:
主站蜘蛛池模板: 浙江工业冷却塔-菱电冷却塔厂家 - 浙江菱电冷却设备有限公司 | 干洗店加盟_洗衣店加盟_干洗店设备-伊蔻干洗「武汉总部」 | 代理记账_免费注册公司_营业执照代办_资质代办-【乐财汇】 | 学叉车培训|叉车证报名|叉车查询|叉车证怎么考-工程机械培训网 | 西点培训学校_法式西点培训班_西点师培训_西点蛋糕培训-广州烘趣西点烘焙培训学院 | 微学堂-电动能源汽车评测_电动车性能分享网 | 耐腐蚀泵,耐腐蚀真空泵,玻璃钢真空泵-淄博华舜耐腐蚀真空泵有限公司 | 标准件-非标紧固件-不锈钢螺栓-非标不锈钢螺丝-非标螺母厂家-三角牙锁紧自攻-南京宝宇标准件有限公司 | 氨水-液氨-工业氨水-氨水生产厂家-辽宁顺程化工 | 高考志愿规划师_高考规划师_高考培训师_高报师_升学规划师_高考志愿规划师培训认证机构「向阳生涯」 | 企典软件一站式企业管理平台,可私有、本地化部署!在线CRM客户关系管理系统|移动办公OA管理系统|HR人事管理系统|人力 | 干洗店加盟_洗衣店加盟_干洗店设备-伊蔻干洗「武汉总部」 | 苹果售后维修点查询,苹果iPhone授权售后维修服务中心 – 修果网 拼装地板,悬浮地板厂家,悬浮式拼装运动地板-石家庄博超地板科技有限公司 | 云南成人高考_云南成考网| 粉末包装机,拆包机厂家,价格-上海强牛包装机械设备有限公司 | VOC检测仪-甲醛检测仪-气体报警器-气体检测仪厂家-深恒安科技有限公司 | 东莞办公家具厂家直销-美鑫【免费3D效果图】全国办公桌/会议桌定制 | 冰晶石|碱性嫩黄闪蒸干燥机-有机垃圾烘干设备-草酸钙盘式干燥机-常州市宝康干燥 | 鲁尔圆锥接头多功能测试仪-留置针测试仪-上海威夏环保科技有限公司 | 帽子厂家_帽子工厂_帽子定做_义乌帽厂_帽厂_制帽厂 | 医学动画公司-制作3d医学动画视频-医疗医学演示动画制作-医学三维动画制作公司 | SEO网站优化,关键词排名优化,苏州网站推广-江苏森歌网络 | 雪花制冰机(实验室雪花制冰机)百科 | 爆破器材运输车|烟花爆竹运输车|1-9类危险品厢式运输车|湖北江南专用特种汽车有限公司 | 广州办公室设计,办公室装修,写字楼设计,办公室装修公司_德科 | 云南成考网_云南成人高考报名网 粤丰硕水性环氧地坪漆-防静电自流平厂家-环保地坪涂料代理 | 磁力去毛刺机_去毛刺磁力抛光机_磁力光饰机_磁力滚抛机_精密金属零件去毛刺机厂家-冠古科技 | 篮球架_乒乓球台_足球门_校园_竞技体育器材_厂家_价格-沧州浩然体育器材有限公司 | 石膏基自流平砂浆厂家-高强石膏基保温隔声自流平-轻质抹灰石膏粉砂浆批发-永康市汇利建设有限公司 | 二氧化碳/活性炭投加系统,次氯酸钠发生器,紫外线消毒设备|广州新奥 | 搪玻璃冷凝器_厂家-越宏化工设备| 刚性-柔性防水套管-橡胶伸缩接头-波纹管补偿器-启腾供水材料有限公司 | 天津蒸汽/热水锅炉-电锅炉安装维修直销厂家-天津鑫淼暖通设备有限公司 | RV减速机-蜗轮蜗杆减速机-洗车机减速机-减速机厂家-艾思捷 | 中空玻璃生产线,玻璃加工设备,全自动封胶线,铝条折弯机,双组份打胶机,丁基胶/卧式/立式全自动涂布机,玻璃设备-山东昌盛数控设备有限公司 | 碎石机设备-欧版反击破-欧版颚式破碎机(站)厂家_山东奥凯诺机械 高低温试验箱-模拟高低温试验箱订制-北京普桑达仪器科技有限公司【官网】 | 烟气换热器_GGH烟气换热器_空气预热器_高温气气换热器-青岛康景辉 | 超声波电磁流量计-液位计-孔板流量计-料位计-江苏信仪自动化仪表有限公司 | 无锡网站建设-做网站-建网站-网页设计制作-阿凡达建站公司 | 杭州可当科技有限公司—流量卡_随身WiFi_AI摄像头一站式解决方案 | 等离子表面处理机-等离子表面活化机-真空等离子清洗机-深圳市东信高科自动化设备有限公司 |