中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

常見Java應用如何關閉

發布時間:2021-06-26 13:34:27 來源:億速云 閱讀:214 作者:chen 欄目:web開發

這篇文章主要介紹“常見Java應用如何關閉”,在日常操作中,相信很多人在常見Java應用如何關閉問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”常見Java應用如何關閉”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

一、前言

在我們進行系統升級的時候,往往需要關閉我們的應用,然后重啟。在關閉應用前,我們希望做一些前置操作,比如關閉數據庫、redis連接,清理zookeeper的臨時節點,釋放分布式鎖,持久化緩存數據等等。

二、Linux的信號機制

在linux上,我們關閉進程主要是使用 kill 的方式。

當執行該命令以后,linux會向進程發送一個信號,進程收到以后之后,可以做一些清理工作。

kill 命令默認的信號值為 15 ,即 SIGTERM 信號。

通過 kill -l 查看linux支持哪些信號:

常見Java應用如何關閉

linux提供了 signal() api,可以將信號處理函數注冊上去:

#include <signal.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <stdbool.h>  static void gracefulClose(int sig)   {     printf("執行清理工作\n");     printf("JVM 已關閉\n");     exit(0);    //正常關閉 }  int main(int argc,char *argv[])   {     if(signal(SIGTERM,gracefulClose) == SIG_ERR)         exit(-1);      printf("JVM 已啟動\n");      while(true)     {         // 執行工作         sleep(1);     } }

三、Java提供的Shutdown Hook

Java并不支持類似于linux的信號機制,但是提供了 Runtime.addShutdownHook(Thread hook) 的api。

在JVM關閉前,會并發執行各個Hook線程。

public class ShutdownHook {      public static void main(String[] args) throws InterruptedException {         Runtime.getRuntime().addShutdownHook(new DbShutdownWork());         System.out.println("JVM 已啟動");          while(true){             Thread.sleep(10L);         }     }      static class DbShutdownWork extends Thread{         public void run(){             System.out.println("關閉數據庫連接");         }     } }

四、Spring Boot提供的優雅關閉功能

我們一般采用如下的方式,啟動一個Spring boot應用:

public static void main(String[] args) throws Exception {       SpringApplication.run(SampleController.class, args); }

SpringApplication.run()代碼如下,會調用到refreshContext(context)方法:

public ConfigurableApplicationContext run(String... args) {       StopWatch stopWatch = new StopWatch();     stopWatch.start();     ConfigurableApplicationContext context = null;     FailureAnalyzers analyzers = null;     configureHeadlessProperty();     SpringApplicationRunListeners listeners = getRunListeners(args);     listeners.started();     try {         ApplicationArguments applicationArguments = new DefaultApplicationArguments(                 args);         ConfigurableEnvironment environment = prepareEnvironment(listeners,                 applicationArguments);         Banner printedBanner = printBanner(environment);         context = createApplicationContext();         analyzers = new FailureAnalyzers(context);         prepareContext(context, environment, listeners, applicationArguments,                 printedBanner);         refreshContext(context);         afterRefresh(context, applicationArguments);         listeners.finished(context, null);         stopWatch.stop();         if (this.logStartupInfo) {             new StartupInfoLogger(this.mainApplicationClass)                     .logStarted(getApplicationLog(), stopWatch);         }         return context;     }     catch (Throwable ex) {         handleRunFailure(context, listeners, analyzers, ex);         throw new IllegalStateException(ex);     } }

refreshContext()方法比較簡單:

private void refreshContext(ConfigurableApplicationContext context) {       refresh(context);   //調用ApplicationContext.refresh()     if (this.registerShutdownHook) {        //registerShutdownHook默認值為true         try {             context.registerShutdownHook();         }         catch (AccessControlException ex) {             // Not allowed in some environments.         }     } }

AbstractApplicationContext.registerShutdownHook()代碼:

public void registerShutdownHook() {       if (this.shutdownHook == null) {         this.shutdownHook = new Thread() {             @Override             public void run() {                 synchronized (startupShutdownMonitor) {                     doClose();                 }             }         };         Runtime.getRuntime().addShutdownHook(this.shutdownHook);     } }

很明顯,Spring  boot通過在啟動時,向JVM注冊一個ShutdownHook,從而實現JVM關閉前,正常關閉Spring容器。而Spring在銷毀時,會依次調用bean的destroy動作來銷毀。

五、Dubbo的優雅關閉策略

Dubbo同樣是基于ShutdownHook實現的。

AbstractConfig的static代碼:

static {       Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {         public void run() {             if (logger.isInfoEnabled()) {                 logger.info("Run shutdown hook now.");             }             ProtocolConfig.destroyAll();         }     }, "DubboShutdownHook")); }

六、總結

只要我們的應用運行在linux平臺上,所有的優雅關閉方案都是基于linux提供的信號機制提供的,JVM也是如此。

Java并沒有為我們提供與之一一對應的api,而是給出了個ShutdownHook機制,也能達到類似的效果,缺點是我們無法得知JVM關閉的原因。

像dubbo、spring  boot等成熟的開源框架,都實現了自動注冊ShutdownHook的功能,從而避免使用者忘記調用優雅關閉api引發問題,降低框架的使用難度。

到此,關于“常見Java應用如何關閉”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

鹤岗市| 南通市| 汕尾市| 象山县| 定边县| 玛曲县| 南木林县| 通化县| 武城县| 新化县| 许昌市| 灌南县| 衢州市| 岗巴县| 镶黄旗| 阳朔县| 宕昌县| 奉化市| 新邵县| 宝坻区| 乡宁县| 江西省| 乐至县| 紫阳县| 革吉县| 贵南县| 镇原县| 大英县| 九寨沟县| 泸水县| 星子县| 远安县| 富阳市| 海宁市| 买车| 明星| 高雄县| 华蓥市| 新巴尔虎右旗| 如东县| 平塘县|