国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

別再用 kill -9 了,這才是微服務上下線的正確姿勢!

開發 后端
就上線來說,如果組件或者容器沒有啟動成功,就不應該對外暴露服務,對于下線來說,如果機器已經停機了,就應該保證服務已下線,如此可避免上游流量進入不健康的機器。

 對于微服務來說,服務的優雅上下線是必要的。

就上線來說,如果組件或者容器沒有啟動成功,就不應該對外暴露服務,對于下線來說,如果機器已經停機了,就應該保證服務已下線,如此可避免上游流量進入不健康的機器。

優雅下線

基礎下線(Spring/SpringBoot/內置容器)

首先JVM本身是支持通過shutdownHook的方式優雅停機的。 

  1. Runtime.getRuntime().addShutdownHook(new Thread() {  
  2.     @Override  
  3.     public void run() {  
  4.         close();  
  5.     }  
  6. }); 

此方式支持在以下幾種場景優雅停機:

程序正常退出

使用System.exit()

終端使用Ctrl+C

使用Kill pid干掉進程

那么如果你偏偏要kill -9 程序肯定是不知所措的。

而在Springboot中,其實已經幫你實現好了一個shutdownHook,支持響應Ctrl+c或者kill -15 TERM信號。

隨便啟動一個應用,然后Ctrl+c一下,觀察日志就可知, 它在 AnnotationConfigEmbeddedWebApplicationContext 這個類中打印出了疑似Closing...的日志,真正的實現邏輯在其父類 AbstractApplicationContext 中(這個其實是spring中的類,意味著什么呢,在spring中就支持了對優雅停機的擴展)。

Spring Boot 系列教程和示例源碼看這里:https://github.com/javastacks/spring-boot-best-practice 

  1. public void registerShutdownHook() {  
  2.     if (this.shutdownHook == null) {  
  3.         this.shutdownHook = new Thread() {  
  4.             public void run() {  
  5.                 synchronized(AbstractApplicationContext.this.startupShutdownMonitor) {  
  6.                     AbstractApplicationContext.this.doClose();  
  7.                 }  
  8.             }  
  9.         };  
  10.         Runtime.getRuntime().addShutdownHook(this.shutdownHook);  
  11.     } 
  12.  
  13. public void destroy() {  
  14.     this.close();  
  15.  
  16. public void close() {  
  17.     Object var1 = this.startupShutdownMonitor; 
  18.      synchronized(this.startupShutdownMonitor) { 
  19.          this.doClose();  
  20.         if (this.shutdownHook != null) {  
  21.             try {  
  22.                 Runtime.getRuntime().removeShutdownHook(this.shutdownHook);  
  23.             } catch (IllegalStateException var4) {  
  24.                 ;  
  25.             }  
  26.         }  
  27.     }  
  28.  
  29. protected void doClose() {  
  30.     if (this.active.get() && this.closed.compareAndSet(false, true)) {  
  31.         if (this.logger.isInfoEnabled()) {  
  32.             this.logger.info("Closing " + this);  
  33.         }  
  34.         LiveBeansView.unregisterApplicationContext(this);  
  35.         try {  
  36.             this.publishEvent((ApplicationEvent)(new ContextClosedEvent(this)));  
  37.         } catch (Throwable var3) {  
  38.             this.logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", var3);  
  39.         }  
  40.         if (this.lifecycleProcessor != null) {  
  41.             try {  
  42.                 this.lifecycleProcessor.onClose();  
  43.             } catch (Throwable var2) {  
  44.                 this.logger.warn("Exception thrown from LifecycleProcessor on context close", var2);  
  45.             }  
  46.         }  
  47.         this.destroyBeans();  
  48.         this.closeBeanFactory();  
  49.         this.onClose();  
  50.         this.active.set(false);  
  51.     }   

我們能對它做些什么呢,其實很明顯,在doClose方法中它發布了一個ContextClosedEvent的方法,不就是給我們擴展用的么。

于是我們可以寫個監聽器監聽ContextClosedEvent,在發生事件的時候做下線邏輯,對微服務來說即是從注冊中心中注銷掉服務。 

  1. @Component  
  2. public class GracefulShutdownListener implements ApplicationListener<ContextClosedEvent> {  
  3.         @Override  
  4.     public void onApplicationEvent(ContextClosedEvent contextClosedEvent){  
  5.        //注銷邏輯  
  6.        zookeeperRegistry.unregister(mCurrentServiceURL);  
  7.        ...  
  8.     }  

可能會有疑問的是,微服務中一般來說,注銷服務往往是優雅下線的第一步,接著才會執行停機操作,那么這個時候流量進來怎么辦呢?

個人會建議是,在注銷服務之后就可開啟請求擋板拒絕流量了,通過微服務框架本身的故障轉移功能去處理被拒絕的流量即可。另外,關注公眾號Java技術棧,在后臺回復:面試,可以獲取我整理的 Java、Spring Boot 系列面試題和答案,非常齊全。

Docker中的下線

好有人說了,我用docker部署服務,支不支持優雅下線。

那來看看docker的一些停止命令都會干些啥:

一般來說,正常人可能會用docker stop或者docker kill 命令去關閉容器(當然如果上一步注冊了USR2自定義信息,可能會通過docker exec kill -12去關閉)。

對于docker stop來說,它會發一個SIGTERM(kill -15 term信息)給容器的PID1進程,并且默認會等待10s,再發送一個SIGKILL(kill -9 信息)給PID1。

那么很明顯,docker stop允許程序有個默認10s的反應時間去做一下優雅停機的操作,程序只要能對kill -15 信號做些反應就好了,如上一步描述。那么這是比較良好的方式。

當然如果shutdownHook方法執行了個50s,那肯定不優雅了。可以通過docker stop -t 加上等待時間。

外置容器的shutdown腳本(Jetty)

如果非要用外置容器方式部署(個人認為浪費資源并提升復雜度)。那么能不能優雅停機呢。

可以當然也是可以的,這里有兩種方式:

首先RPC框架本身提供優雅上下線接口,以供調用來結束整個應用的生命周期,并且提供擴展點供開發者自定義服務下線自身的停機邏輯。同時調用該接口的操作會封裝成一個preStop操作固化在jetty或者其他容器的shutdown腳本中,保證在容器停止之前先調用下線接口結束掉整個應用的生命周期。shutdown腳本中執行類發起下線服務 -> 關閉端口 -> 檢查下線服務直至完成 -> 關閉容器的流程。

而更簡單的另一種方法是直接在腳本中加入kill -15命令。

優雅上線

優雅上線相對來說可能會更加困難一些,因為沒有什么默認的實現方式,但是總之呢,一個原則就是確保端口存在之后才上線服務。

springboot內置容器優雅上線

這個就很簡單了,并且業界在應用層面的優雅上線均是在內置容器的前提下實現的,并且還可以配合一些列健康檢查做文章。Spring Boot 優雅關閉新姿勢,看看這篇。

參看sofa-boot的健康檢查的源碼,它會在程序啟動的時候先對springboot的組件做一些健康檢查,然后再對它自己搞得sofa的一些中間件做健康檢查,整個健康檢查的流程完畢之后(sofaboot 目前是沒法對自身應用層面做健康檢查的,它有寫相關接口,但是寫死了port is ready...)才會暴露服務或者說優雅上線,那么它健康檢查的時機是什么時候呢: 

  1. @Override  
  2. public void onApplicationEvent(ContextRefreshedEvent event) {  
  3.     healthCheckerProcessor.init();  
  4.     healthIndicatorProcessor.init();  
  5.     afterHealthCheckCallbackProcessor.init();  
  6.     publishBeforeHealthCheckEvent();  
  7.     readinessHealthCheck();  

可以看到它是監聽了ContextRefreshedEvent這個事件。在內置容器模式中,內置容器模式的start方法是在refreshContext方法中,方法執行完成之后發布一個ContextRefreshedEvent事件,也就是說在監聽到這個事件的時候,內置容器必然是啟動成功了的。

但ContextRefreshedEvent這個事件,在一些特定場景中由于種種原因,ContextRefreshedEvent會被監聽到多次,沒有辦法保證當前是最后一次event,從而正確執行優雅上線邏輯。

在springboot中還有一個更加靠后的事件,叫做ApplicationReadyEvent,它的發布藏在了afterRefresh還要后面的那一句listeners.finished(context, null)中,完完全全可以保證內置容器 端口已經存在了,所以我們可以監聽這個事件去做優雅上線的邏輯,甚至可以把中間件相關的健康檢查集成在這里。 

  1. @Component  
  2. public class GracefulStartupListener implements ApplicationListener<ApplicationReadyEvent> {      
  3.     @Override  
  4.     public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent){  
  5.        //注冊邏輯 優雅上線  
  6.        apiRegister.register(urls);  
  7.        ...  
  8.     }  

外置容器(Jetty)優雅上線

目前大多數應用的部署模式不管是jetty部署模式還是docker部署模式(同樣使用jetty鏡像),本質上用的都是外置容器。那么這個情況就比較困難了,至少在應用層面無法觀察到外部容器的運行狀態,并且容器本身沒有提供什么hook給你實現。

那么和優雅上線一樣,需要RPC框架提供優雅上線接口來初始化整個應用的生命周期,并且提供擴展點給開發者供執行自定義的上線邏輯(上報版本探測信息等)。同樣將調用這個接口封裝成一個postStart操作,固化在jetty等外置容器的startup腳本中,保證應用在容器啟動之后在上線。容器執行類似啟動容器 -> 健康檢查 -> 上線服務邏輯 -> 健康上線服務直至完成 的流程。

 

 

責任編輯:龐桂玉 來源: Java技術棧
相關推薦

2025-08-04 01:55:00

2025-01-10 06:30:00

2021-05-25 09:30:44

kill -9Linux kill -9 pid

2024-09-25 08:22:06

2019-01-02 10:49:54

Tomcat內存HotSpot VM

2021-11-05 10:36:19

性能優化實踐

2020-08-05 07:27:54

SQL優化分類

2023-10-26 16:33:59

float 布局前段CSS

2019-06-27 17:18:02

Java日志編程語言

2024-12-26 07:47:20

2018-07-30 11:21:30

華為云

2020-06-28 16:28:24

Windows 10WindowsU盤

2017-06-12 16:17:07

2024-09-09 11:11:45

2021-05-26 05:33:30

5G網絡運營商

2025-01-15 12:31:46

2025-04-25 10:28:40

2025-08-13 03:00:00

2025-05-19 04:00:00

2025-03-12 11:14:45

點贊
收藏

51CTO技術棧公眾號

在线免费看h| 先锋影音久久久| 欧美电影免费提供在线观看| 在线视频xx| 成人激情av网| 日韩亚洲视频在线| 久久不见久久见中文字幕免费| 自拍视频国产精品| 乡村艳史在线观看| 欧美va亚洲va| sese一区| 日本韩国精品在线| 8×8x拔擦拔擦在线视频网站| 国产欧美日韩久久| 精品中文字幕av| 成人激情免费网站| a级免费在线观看| 国产麻豆精品视频| 男女啪啪的视频| 另类小说欧美激情| 亚洲欧美影院| 久久99精品久久久久久久久久久久 | 2019中文字幕在线观看| 久久在线观看| 色综合久久天天综线观看| 久久久久亚洲精品中文字幕| 理论片在线不卡免费观看| 中文.日本.精品| 久久精品国产成人精品| 欧一区二区三区| 国产69精品久久久| 国产探花一区| 成人欧美一区二区| 亚洲欧美日韩一区在线观看| 婷婷久久伊人| 成人午夜激情片| 亚洲老女人av| 午夜欧美大尺度福利影院在线看| 日本一区高清| 欧美美女激情18p| 国产第一页在线| 视频一区视频二区国产精品 | 欧美日韩在线三级| 日韩在线资源| 欧美精品一区二区蜜臀亚洲| 91av亚洲| 久久久久久久久久久成人| 国产精品片aa在线观看| 成人在线视频电影| 美女视频网站黄色亚洲| 噜噜噜久久亚洲精品国产品麻豆| 国产欧美一区二区精品仙草咪| 毛片中文在线观看| 欧美日本国产一区| 韩日精品一区| 国产精品27p| 中文在线一区| 欧美一级欧美一级| 亚洲高清三级视频| 91在线超碰| 欧美一级电影久久| 久久中文字幕一区二区三区| 日韩av一二三四区| 亚洲午夜久久久久久久久电影院| 午夜伦理在线| 最近2019中文字幕大全第二页| 精品在线手机视频| 亚洲午夜精品福利| 一区二区三区不卡视频在线观看| 日本动漫同人动漫在线观看| 欧美—级a级欧美特级ar全黄| 欧美日韩理论| 国产午夜福利视频在线观看| 欧美日韩国产精品一区二区三区四区| 中文字幕在线免费观看视频| 国产成人精品综合| 另类人妖一区二区av| 婷婷六月天丁香| 国产丝袜一区二区三区免费视频| 亚洲影院天堂中文av色| 黄色一级片网址| 亚洲aaa精品| 黄色精品视频| 国产99亚洲| 成人黄色av播放免费| 欧美日本在线| 免费99热在线观看| 精品久久久久久久久久久久久久久久久 | 国产精品视频一区二区三区四蜜臂| 成人在线一区二区| 国产福利一区二区| 国产人成在线观看| 久久99久久99精品免观看粉嫩| 国产视频一区免费看| 91色.com| 欧美激情第99页| 欧美亚洲三级| 一二三四社区在线视频| 中文字幕亚洲在线| 先锋a资源在线看亚洲| 快色在线观看| 另类视频在线观看| 久久爱www久久做| 在线观看的av| 麻豆精品一二三| 啦啦啦在线视频免费观看高清中文| 亚洲欧美综合v| 亚洲一区二区网站| 日韩毛片在线一区二区毛片| 97超视频免费观看| 97久久超碰国产精品电影| 99色在线观看| 日本一区二区久久精品| 色婷婷精品久久二区二区蜜臂av| 欧美人与动xxxxz0oz| 国产a级一级片| 国产一区二区三区日韩欧美| 视频一区国产视频| 免费超碰在线| 国产精品一区二区不卡视频| 午夜不卡在线视频| 欧美老女人另类| 男人在线视频资源| 97视频免费在线看| 国产精品人人做人人爽人人添| 爱情电影网av一区二区| 久久福利一区二区| 日韩激情在线视频| 黄色资源网久久资源365| 污污在线观看| 天堂一区二区三区| 精品国产91洋老外米糕| 免费在线观看视频一区| 欧美性猛片xxxxx免费中国| 日本一区二区三区免费观看| 欧美色大人视频| 极品日韩av| 国产在线看片| 婷婷四房综合激情五月| 日韩欧美一二三四区| 日本亚洲免费观看| 色偷偷色偷偷色偷偷在线视频| 正在播放一区| 亚洲男人第一av网站| 国产精品99久久久| 国外成人福利视频| av免费中文字幕| 欧日韩在线观看| 欧美日韩黄色大片| 亚洲综合二区| 伊人久久综合一区二区| 人妻无码久久一区二区三区免费| 中文字幕av一区中文字幕天堂 | 日本在线看片免费人成视1000| 国产欧美日本在线| 精品国产百合女同互慰| 丁香婷婷综合五月| 精品国内亚洲2022精品成人| 色网在线视频| 精品国产一区二区三区麻豆小说| 亚洲成人黄色在线| 久久久国际精品| 香蕉国产精品| 亚洲啊v在线| 国产一级视频| 欧美三级网色| 欧美激情第1页| 欧美午夜精品一区二区三区| 国产精品自拍网站| 一本色道久久综合亚洲精品酒店| 9191在线观看| 亚洲午夜精品久久久久久人妖| 热久久99这里有精品| 91精品国产一区二区三区蜜臀| 成人免费av在线| 亚洲色图网站| 欧美激情啪啪| 久久精品国产亚洲a∨麻豆| 吴梦梦av在线| 国产成人午夜视频网址 | 97视频精彩视频在线观看| 国产aaa免费视频| 成人免费淫片视频软件| 亚洲欧美日韩在线一区| 亚洲国产欧美日韩另类综合| 美腿丝袜在线亚洲一区| 中日韩免视频上线全都免费| 亚洲大胆人体大胆做受1| 国产福利在线免费| 欧美三日本三级少妇三99| 欧美激情一二区| 日韩欧美第一区| 亚洲综合激情网| 国产成人精品影院| 欧美久久影院| 国产精品一区二区三区四区在线观看| av在线免费一区| 欧美成人三级在线播放| 亚洲视频在线二区| 亚洲va欧美va国产综合剧情|