日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

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

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

瀏覽:244日期: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
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
精品黄色一级片| 麻豆国产一区| 蘑菇福利视频一区播放| 人人爽香蕉精品| 美女精品在线| 亚洲不卡系列| 鲁大师影院一区二区三区| 天堂va在线高清一区| 青草久久视频| 亚洲精品进入| 视频一区中文字幕| 99亚洲精品| 久热综合在线亚洲精品| 久久99伊人| 亚洲深深色噜噜狠狠爱网站 | 成人在线视频区| 国产模特精品视频久久久久| 最新亚洲激情| 欧美日韩国产高清| 久久97视频| 国产麻豆一区| 日韩av免费大片| 国产69精品久久| 黑森林国产精品av| 欧美~级网站不卡| 韩国精品主播一区二区在线观看| 久久久精品日韩| 女同性一区二区三区人了人一| 精品视频97| 麻豆91精品91久久久的内涵| 国产女优一区| 欧美1区二区| 久久国产婷婷国产香蕉| 亚洲v在线看| 一区在线免费| 国产亚洲一级| 蜜臀精品一区二区三区在线观看| 亚洲精华国产欧美| 欧美日韩一区二区国产| 欧美a一区二区| 日韩精品欧美大片| 久久精品国产免费| 亚洲经典在线| 亚洲综合日韩| 98精品视频| 丝袜美腿亚洲一区| 国产精品久久久久久久久久齐齐| 欧美日韩免费观看一区=区三区 | 国产精品久久| 国产精品麻豆久久| 国产亚洲在线观看| 鲁大师影院一区二区三区| 久久国产影院| 9色精品在线| 欧美在线观看视频一区| 久久xxxx精品视频| 国产精品毛片| 日本精品久久| 国产一区二区三区日韩精品| 亚洲黄色网址| 中文字幕高清在线播放| 精品视频高潮| 国产亚洲在线观看| 欧美不卡在线| 婷婷综合六月| 麻豆久久久久久久| 亚洲一区导航| 欧美搞黄网站| 成人美女视频| 日本不卡高清| 水野朝阳av一区二区三区| 日韩一区三区| 蜜桃久久久久| 欧美精品中文| 久久精品国产亚洲一区二区三区| 亚洲激情偷拍| 欧美亚洲国产激情| 久久夜夜操妹子| 捆绑调教日本一区二区三区| 麻豆一区二区三| 亚洲涩涩av| 狠狠干成人综合网| 黄色国产精品| 视频一区二区三区中文字幕| 日韩av在线中文字幕| 国产精品亚洲四区在线观看| 青青久久av| 成人在线免费观看91| 日韩精选在线| 久久不卡国产精品一区二区| 国产麻豆精品久久| 国产精品视频一区二区三区综合| 日韩欧美久久| 91成人在线精品视频| 国产精品欧美大片| 久久精品国产网站| 在线亚洲观看| 青青草国产精品亚洲专区无| 午夜日韩在线| 国产极品一区| 伊人精品久久| 国产高清一区二区| 国产精品日韩欧美一区| 99精品在线| 国产欧美一区二区三区精品观看| 日韩精品欧美| 日韩二区三区四区| 亚洲精品va| 免费久久99精品国产自在现线| 国产精品任我爽爆在线播放 | 福利一区二区三区视频在线观看| 亚洲免费婷婷| 丝袜亚洲精品中文字幕一区| 久久亚洲图片| 日韩高清一区在线| 国产私拍福利精品视频二区| 亚洲理论在线| 日韩成人午夜精品| 久久国内精品视频| 日韩精品午夜视频| 免费一级欧美在线观看视频| 亚洲精品成人一区| 日韩欧美激情电影| 日韩中出av| 狠狠爱www人成狠狠爱综合网| 蜜桃成人av| 久久久久国产精品一区三寸| 久久久久九九精品影院| 日产欧产美韩系列久久99| 欧美国产视频| 久久久国产精品网站| 精品日产乱码久久久久久仙踪林| 精品九九久久| 九九久久电影| 亚洲理论在线| 精品一区二区三区中文字幕在线| 免费在线亚洲欧美| 99久久九九| 国产视频一区二| 日韩和的一区二在线| 国产高清日韩| 国产一区二区三区亚洲| 欧美日韩国产一区精品一区| 欧美综合二区| 国产毛片精品久久| 久久青青视频| 亚洲一区二区动漫| 国产精品久久久久9999高清| 日韩精品首页| 欧美va天堂在线| 中文精品电影| 亚洲综合欧美| 国产精品视区| 日韩一区自拍| 日韩精品免费观看视频| 综合激情视频| 尹人成人综合网| 国产一区2区在线观看| 日本在线视频一区二区| 亚洲最新av| 99日韩精品| 999国产精品| 久久久久久色| 99国产精品免费视频观看| 国产欧美一区二区精品久久久| 亚洲a在线视频| 99热精品久久| 国产一区二区三区四区五区 | 亚洲日产国产精品| 欧美国产不卡| 日韩三区四区| 亚洲一区免费| 久久免费高清| 久久精品资源| 久久国产精品色av免费看| 精品一区在线| 韩国三级一区| 美女精品一区二区| 日韩欧美在线精品| 香蕉久久国产| 国产欧美一区二区三区米奇| 亚洲最大av| 综合在线一区| 中文字幕一区二区三区四区久久 | 久久一区精品| 国产精品18| 欧美激情视频一区二区三区免费 | 国产亚洲精品美女久久久久久久久久| 伊人成人网在线看| 欧美影院三区| 亚洲女同中文字幕| 香蕉久久国产| 免费在线观看精品| 综合在线一区| 日本精品久久| 久久精品国产99国产| 色婷婷色综合| 国产国产精品| 国产视频亚洲| 深夜福利亚洲|