自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

面試官:你知道Dubbo怎么做優(yōu)雅上下線的嗎?你:優(yōu)雅上下線是啥?

開發(fā) 開發(fā)工具
最近無論是校招還是社招,都進行的如火如荼,我也承擔了很多的面試工作,在一次面試過程中,和候選人聊了一些關于Dubbo的知識。

[[394301]]

最近無論是校招還是社招,都進行的如火如荼,我也承擔了很多的面試工作,在一次面試過程中,和候選人聊了一些關于Dubbo的知識。

Dubbo是一個比較著名的RPC框架,很多人對于他的一些網絡通信、通信協(xié)議、動態(tài)代理等等都有一定的了解,這位候選人也一樣。

但是,我接下來問了他一個問題:你們在使用Dubbo的時候,應用如果重啟,怎么保證一個請求不會被中斷處理的呢?

他沒怎么說的上來,我以為他不理解我的問題,我接著問他:我就是想問下Dubbo是如何做優(yōu)雅上下線的你知道嗎?

接著他問我:優(yōu)雅上下線是啥??

好吧。

這篇文章,我來介紹一下這個知識點吧。

優(yōu)雅上下線

關于"優(yōu)雅上下線"這個詞,我沒找到官方的解釋,我嘗試解釋一下這是什么。

首先,上線、下線大家一定都很清楚,比如我們一次應用發(fā)布過程中,就需要先將應用服務停掉,然后再把服務啟動起來。這個過程就包含了一次下線和一次上線。

那么,"優(yōu)雅"怎么理解呢?

先說什么情況我們認為不優(yōu)雅:

1、服務停止時,沒有關閉對應的監(jiān)控,導致應用停止后發(fā)生大量報警。

2、應用停止時,沒有通知外部調用方,很多請求還會過來,導致很多調用失敗。

3、應用停止時,有線程正在執(zhí)行中,執(zhí)行了一半,JVM進程就被干掉了。

4、應用啟動時,服務還沒準備好,就開始對外提供服務,導致很多失敗調用。

5、應用啟動時,沒有檢查應用的健康狀態(tài),就開始對外提供服務,導致很多失敗調用。

以上,都是我們認為的不優(yōu)雅的情況,那么,反過來,優(yōu)雅上下線就是一種避免上述情況發(fā)生的手段。

一個應用的優(yōu)雅上下線涉及到的內容其實有很多,從底層的操作系統(tǒng)、容器層面,到編程語言、框架層面,再到應用架構層面,涉及到的知識很廣泛。

其實,優(yōu)雅上下線中,最重要的還是優(yōu)雅下線。因為如果下線過程不優(yōu)雅的話,就會發(fā)生很多調用失敗了、服務找不到等問題。所以很多時候,大家也會提優(yōu)雅停機這樣的概念。

本文后面介紹的優(yōu)雅上下線也重點關注優(yōu)雅停機的過程。

操作系統(tǒng)&容器的優(yōu)雅上下線

關于操作系統(tǒng),我之前有一篇文章專門介紹過這個話題,可能大家沒有注意到,那時候介紹的主題是為什么不能在線上機器中隨便執(zhí)行kill -9。

其實,這背后的思考就是優(yōu)雅上下線。

我們知道,kill -9之所以不建議使用,是因為kill -9特別強硬,系統(tǒng)會發(fā)出SIGKILL信號,他要求接收到該信號的程序應該立即結束運行,不能被阻塞或者忽略。

這個過程顯然是不優(yōu)雅的,因為應用立刻停止的話,就沒辦法做收尾動作。而更優(yōu)雅的方式是kill -15。

當使用kill -15時,系統(tǒng)會發(fā)送一個SIGTERM的信號給對應的程序。當程序接收到該信號后,具體要如何處理是自己可以決定的。

kill -15會通知到應用程序,這就是操作系統(tǒng)對于優(yōu)雅上下線的最基本的支持。

以前,在操作系統(tǒng)之上就是應用程序了,但是,自從容器化技術推出之后,在操作系統(tǒng)和應用程序之間,多了一個容器層,而Docker、k8s等容器其實也是支持優(yōu)雅上下線的。

如Docker中同樣提供了兩個命令, docker stop 和 docker kill

docker stop就像kill -15一樣,他會向容器內的進程發(fā)送SIGTERM信號,在10S之后(可通過參數(shù)指定)再發(fā)送SIGKILL信號。

而docker kill就像kill -9,直接發(fā)送SIGKILL信號。

JVM的優(yōu)雅上下線

在操作系統(tǒng)、容器等對優(yōu)雅上下線有了基本的支持之后,在接收到docker stop、kill -15等命令后,會通知應用進程進行進程關閉。

而Java應用在運行時就是一個獨立運行的進程,這個進程是如何關閉的呢?

Java程序的終止運行是基于JVM的關閉實現(xiàn)的,JVM關閉方式分為正常關閉、強制關閉和異常關閉3種。

這其中,正常關閉就是支持優(yōu)雅上下線的。正常關閉過程中,JVM可以做一些清理動作,比如刪除臨時文件。

當然,開發(fā)者也是可以自定義做一些額外的事情的,比如通知應用框架優(yōu)雅上下線操作。

而這種機制是通過JDK中提供的shutdown hook實現(xiàn)的。JDK提供了Java.Runtime.addShutdownHook(Thread hook)方法,可以注冊一個JVM關閉的鉤子。

例子如下:

  1. package com.hollis; 
  2.  
  3.     public class ShutdownHookTest { 
  4.  
  5.         public static void main(String[] args) { 
  6.  
  7.             boolean flag = true
  8.  
  9.             Runtime.getRuntime().addShutdownHook(new Thread(() -> { 
  10.  
  11.                 System.out.println("hook execute..."); 
  12.  
  13.             })); 
  14.  
  15.             while (flag) { 
  16.  
  17.                 // app is runing 
  18.  
  19.             } 
  20.  
  21.             System.out.println("main thread execute end..."); 
  22.  
  23.         } 
  24.  
  25.     } 

執(zhí)行命令:

  1. jps 
  2.  6520 ShutdownHookTest 
  3.  6521 Jps 
  4. kill 6520 

控制臺輸出內容:

  1. hook execute... 
  2.  
  3.  Process finished with exit code 143 (interrupted by signal 15: SIGTERM) 

可以看到,當我們使用kill(默認kill -15)關閉進程的時候,程序會先執(zhí)行我注冊的shutdownHook,然后再退出,并且會給出一個提示:interrupted by signal 15: SIGTERM

Spring的優(yōu)雅上下線

有了JVM提供的shutdown hook之后,很多框架都可以通過這個機制來做優(yōu)雅下線的支持。

比如Spring,他就會向JVM注冊一個shutdown hook,在接收到關閉通知的時候,進行bean的銷毀,容器的銷毀處理等操作。

同時,作為一個成熟的框架,Spring也提供了事件機制,可以借助這個機制實現(xiàn)更多的優(yōu)雅上下線功能。

ApplicationListener是Spring事件機制的一部分,與抽象類ApplicationEvent類配合來完成ApplicationContext的事件機制。

開發(fā)者可以實現(xiàn)ApplicationListener接口,監(jiān)聽到 Spring 容器的關閉事件(ContextClosedEvent),來做一些特殊的處理:

  1. @Component 
  2.  
  3.     public class MyListener implements ApplicationListener<ContextClosedEvent> { 
  4.  
  5.         @Override 
  6.  
  7.         public void onApplicationEvent(ContextClosedEvent event) { 
  8.  
  9.             // 做容器關閉之前的清理工作 
  10.  
  11.         } 
  12.  
  13.     } 

Dubbo的優(yōu)雅上下線

因為Spring中提供了ApplicationListener接口,幫助我們來監(jiān)聽容器關閉事件,那么,很多web容器、框架等就可以借助這個機制來做自己的優(yōu)雅上下線操作。

如tomcat、dubbo等都是這么做的。

這里簡答說一下Dubbo的,在Dubbo的官網中,有關于優(yōu)雅停機的介紹:

應用在停機時,接收到關閉通知時,會先把自己標記為不接受(發(fā)起)新請求,然后再等待10s(默認是10秒)的時候,等執(zhí)行中的線程執(zhí)行完。

那么,之所以他能做這些事,是因為從操作系統(tǒng)、到JVM、到Spring等都對優(yōu)雅停機做了很好的支持。

關于Dubbo各個版本中具體是如何借助JVM的shutdown hook機制、或者說Spring的事件機制的優(yōu)雅停機,我的一位同事的一篇文章介紹的很清晰,大家可以看下:

https://www.cnkirito.moe/dubbo-gracefully-shutdown/

在從Dubbo 2.5 到 Dubbo 2.7介紹了歷史版本中,Dubbo為了解決優(yōu)雅上下線問題所遇到的問題和方案。

目前,Dubbo中實現(xiàn)方式如下,同樣是用到了Spring的事件機制:

  1. public class SpringExtensionFactory implements ExtensionFactory { 
  2.  
  3.       public static void addApplicationContext(ApplicationContext context) { 
  4.  
  5.           CONTEXTS.add(context); 
  6.  
  7.           if (context instanceof ConfigurableApplicationContext) { 
  8.  
  9.               ((ConfigurableApplicationContext) context).registerShutdownHook(); 
  10.  
  11.               DubboShutdownHook.getDubboShutdownHook().unregister(); 
  12.  
  13.           } 
  14.  
  15.           BeanFactoryUtils.addApplicationListener(context, SHUTDOWN_HOOK_LISTENER); 
  16.  
  17.       } 
  18.  
  19.   } 

總結

本文從操作系統(tǒng)開始,分別介紹了Linux、Docker、JVM、Spring、Dubbo等對優(yōu)雅停機的支持。

可以看到,一個簡單的優(yōu)雅停機功能,上下游需要這么多底層基礎設施和上層應用的支持。

相信通過學習本文,你一定對優(yōu)雅上下線有了更多的了解。

除此之外,我還希望你,通過本文以后,遇到一些實際問題的時候,可以想到文中提到的shutdown hook機制、Spring的event機制。很多時候,這些機制都能幫助我們解決很多問題。

我在工作中,就有很多次使用過這樣的機制的實例,后面有機會給大家介紹幾個實例。

好了,本文的全部內容就是這么多啦,如果對你有幫助,記得一鍵三連哦~

參考 :

https://zhuanlan.zhihu.com/p/29093407

https://www.cnkirito.moe/dubbo-gracefully-shutdown/

 

 

責任編輯:武曉燕 來源: 51CTO專欄
相關推薦

2022-01-27 08:27:23

Dubbo上下線設計

2023-07-14 21:34:40

JVM上下線線程

2021-07-09 10:11:34

Redis云數(shù)據技術

2025-03-17 00:00:00

2024-03-18 14:06:00

停機Spring服務器

2022-11-16 09:27:58

flexbox左右布局均分布局

2022-06-06 15:33:20

線程Java釋放鎖

2015-08-13 10:29:12

面試面試官

2025-03-05 00:00:00

RTKRedux開發(fā)

2024-03-12 10:44:42

2024-05-11 15:11:44

系統(tǒng)軟件部署

2023-10-28 09:13:32

系統(tǒng)面試官架構

2021-01-14 05:23:32

高并發(fā)消息中間件

2021-06-02 11:25:18

線程池Java代碼

2020-03-10 08:01:05

Java堆內存線程共享

2022-07-18 13:59:43

Redis單線程進程

2023-02-28 08:57:06

Spring上下線緩存

2021-09-01 09:44:16

Redis持久化配置

2024-11-06 12:59:42

多線程銷毀線程切換

2022-11-19 18:18:22

Spring架構
點贊
收藏

51CTO技術棧公眾號