精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Spring Boot 實現(xiàn)優(yōu)雅停機的正確姿勢!

開發(fā) 前端
如果暴力的關(guān)閉應(yīng)用程序,比如通過kill -9 <pid>命令強制直接關(guān)閉應(yīng)用程序進程,可能會導(dǎo)致正在執(zhí)行的任務(wù)數(shù)據(jù)丟失或者錯亂,也可能會導(dǎo)致任務(wù)所持有的全局資源等不到釋放,比如當前任務(wù)持有 redis 的鎖,并且沒有設(shè)置過期時間,當任務(wù)突然被終止并且沒有主動釋放鎖,會導(dǎo)致其他進程因無法獲取鎖而不能處理業(yè)務(wù)。

一、背景介紹

什么叫優(yōu)雅停機?

簡單的說,就是向應(yīng)用進程發(fā)出停止指令之后,能保證正在執(zhí)行的業(yè)務(wù)操作不受影響,直到操作運行完畢之后再停止服務(wù)。應(yīng)用程序接收到停止指令之后,會進行如下操作:

  • 1.停止接收新的訪問請求
  • 2.正在處理的請求,等待請求處理完畢;對于內(nèi)部正在執(zhí)行的其他任務(wù),比如定時任務(wù)、mq 消費等等,也要等當前正在執(zhí)行的任務(wù)執(zhí)行完畢,并且不再啟動新的任務(wù)
  • 3.當應(yīng)用準備關(guān)閉的時候,按需向外發(fā)出信號,告知其他應(yīng)用服務(wù)準備接手,以保證服務(wù)高可用

如果暴力的關(guān)閉應(yīng)用程序,比如通過kill -9 <pid>命令強制直接關(guān)閉應(yīng)用程序進程,可能會導(dǎo)致正在執(zhí)行的任務(wù)數(shù)據(jù)丟失或者錯亂,也可能會導(dǎo)致任務(wù)所持有的全局資源等不到釋放,比如當前任務(wù)持有 redis 的鎖,并且沒有設(shè)置過期時間,當任務(wù)突然被終止并且沒有主動釋放鎖,會導(dǎo)致其他進程因無法獲取鎖而不能處理業(yè)務(wù)。

那么如何在不影響正在執(zhí)行的業(yè)務(wù)的情況下,將應(yīng)用程序安全的進行關(guān)閉呢?

二、方案實踐

SpringBoot 官方文檔上,已經(jīng)告訴開發(fā)者只需要實現(xiàn)特定接口即可監(jiān)聽到項目啟動成功與關(guān)閉時的事件,相關(guān)接口如下:

  • CommandLineRunner接口:當應(yīng)用啟動成功后但在開始接受流量之前,會回調(diào)此接口的實現(xiàn)類,也可以實現(xiàn)ApplicationRunner接口,工作的方式與CommandLineRunner與之類似
  • DisposableBean接口:當應(yīng)用正要被銷毀前,會回調(diào)此接口的實現(xiàn)類,也可以使用@PreDestroy注解,被標記的方法也會被調(diào)用

基于此流程,我們可以創(chuàng)建一個服務(wù)監(jiān)聽類,用于監(jiān)聽到項目啟動成功與關(guān)閉時的回調(diào)服務(wù),示例代碼如下:

@Component
public class AppListener implements CommandLineRunner, DisposableBean {

    @Override
    public void run(String... args) throws Exception {
        System.out.println("應(yīng)用啟動成功,預(yù)加載相關(guān)數(shù)據(jù)");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("應(yīng)用正在關(guān)閉,清理相關(guān)數(shù)據(jù)");
    }

}

每一個SpringApplication在啟用的時候,都會向 JVM 注冊一個關(guān)閉鉤子shutdown hook,以確保ApplicationContext在退出的時候,通過這個勾子通知 JVM,實現(xiàn)服務(wù)正常的關(guān)閉,以下介紹的所有關(guān)閉服務(wù)的方法,都是基于這一原理進行實現(xiàn)的。

2.1方法一:通過Actuator的Endpoint機制關(guān)閉服務(wù)

使用此方法,需要先添加spring-boot-starter-actuator監(jiān)控服務(wù)依賴包,

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

默認配置下,shutdown端點是關(guān)閉的,需要在application.properties里配置里面開啟:

management.endpoint.shutdown.enabled=true

雖然Actuator的端點,支持通過JMX或HTTP進行遠程訪問。而shutdown默認配置下是不支持HTTP進行Web訪問的,所以使用HTTP請求進行關(guān)閉時的配置,也需要開啟:

management.endpoints.web.exposure.include=shutdown

最后將SpringBoot服務(wù)啟動之后,使用POST請求類型,調(diào)用以下接口,即可實現(xiàn)關(guān)閉服務(wù)!

http://127.0.0.1:8080/actuator/shutdown

圖片圖片

2.2方法二:使用ApplicationContext的close方法關(guān)閉服務(wù)

如果你不想添加spring-boot-starter-actuator監(jiān)控服務(wù)依賴包來關(guān)停服務(wù),也可以使用ApplicationContext的close方法來關(guān)停服務(wù),他會自動銷毀bean對象并關(guān)停服務(wù)。

只需要在應(yīng)用啟用的時候,獲取ApplicationContext對象,然后在相關(guān)的位置調(diào)用close方法,就可以關(guān)閉服務(wù)。

示例代碼如下:

@SpringBootApplication
publicclass Application {

    public static void main(String[] args) {
      ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);

      try {
         TimeUnit.SECONDS.sleep(10);
      } catch (InterruptedException e) {
         e.printStackTrace();
      }
      //啟動10秒以后,自動關(guān)閉
      context.close();
    }
}

當然我們也可以自己寫一個Controller,獲取對應(yīng)的ApplicationContext對象,通過api操作調(diào)用close方法關(guān)停服務(wù),示例代碼如下:

@RestController
publicclass ShutdownController implements ApplicationContextAware {

    private ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
    }

    /**
     * 關(guān)閉服務(wù)
     */
    @GetMapping("/shutdown")
    public void shutdownContext() {
        ((ConfigurableApplicationContext) context).close();
    }
}

2.3方法三:監(jiān)聽服務(wù)pid,通過kill方式關(guān)閉服務(wù)

通過api方式來關(guān)停服務(wù),在很多人看來并不安全,因為一旦接口泄漏了,意味著用戶可以隨便請求這個接口來關(guān)閉服務(wù),其影響不言而喻,因此很多人建議在服務(wù)端,通過其他的方式來關(guān)閉服務(wù),比如通過進程命令方式來關(guān)停。

在springboot啟動的時候?qū)?yīng)用進程 ID 寫入一個app.pid文件,生成的路徑可以指定,然后通過腳本命令方式來關(guān)閉服務(wù)。

啟動示例代碼如下:

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(Application.class);
        application.addListeners(new ApplicationPidFileWriter("/home/app/project1/app.pid"));
        application.run();
    }
}

通過如下命令方式,可以安全的關(guān)閉服務(wù)。

cat /home/app/project1/app.pid | xargs kill

這種方式,也是目前在linux操作系統(tǒng)中,使用較為普遍的一種解決方案,區(qū)別在于實現(xiàn)的方式可能不同,有的不用寫文件,通過其他方式來獲取應(yīng)用進程 ID。

如果使用kill -9 <pid>的方式關(guān)閉服務(wù),服務(wù)的監(jiān)聽器不會收到任何消息,類似于直接強殺應(yīng)用進程,此方法不可?。?/p>

2.4方法四:使用SpringApplication的exit方法關(guān)閉服務(wù)

通過調(diào)用一個SpringApplication.exit()方法也可以安全的退出程序,同時會返回一個退出碼,這個退出碼可以傳遞給所有的context,最后通過調(diào)用System.exit()可以將這個錯誤碼也傳給JVM。

示例代碼如下:

@SpringBootApplication
publicclass Application {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);

        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //5秒后,關(guān)閉服務(wù)
        exitApplication(context);
    }

    public static void exitApplication(ConfigurableApplicationContext context) {
      //獲取退出碼
        int exitCode = SpringApplication.exit(context, (ExitCodeGenerator) () -> 0);
        //退出碼傳遞給jvm,安全退出程序
        System.exit(exitCode);
    }

}

三、其他監(jiān)聽介紹

3.1ApplicationListener

如果有些服務(wù),比如定時任務(wù),我們想在SpringBoot關(guān)閉數(shù)據(jù)源連接池之前,將其關(guān)閉,可以通過實現(xiàn)ApplicationListener接口,監(jiān)聽bean對象的變化情況,在bean對象銷毀之前,執(zhí)行相關(guān)的關(guān)閉任務(wù)。

示例代碼如下:

@Component
public class JobTaskListener implements ApplicationListener {

    @Override
    public void onApplicationEvent(ApplicationEvent applicationEvent) {
        // 在spring bean容器銷毀之前執(zhí)行的事件,防止數(shù)據(jù)庫連接池在任務(wù)終止前銷毀
        if (applicationEvent instanceof ContextClosedEvent) {
            System.out.println("關(guān)閉相關(guān)的定時任務(wù)");
        }
    }
}

3.2PreDestroy

上文中,我們提到了實現(xiàn)DisposableBean接口,可以監(jiān)聽應(yīng)用關(guān)閉前的回調(diào)處理,其實在自定義的方法上加@PreDestroy注解,也可以實現(xiàn)相同的效果。

示例代碼如下:

@Component
public class AppDestroyConfig {

    @PreDestroy
    public void PreDestroy(){
        System.out.println("應(yīng)用程序正在關(guān)閉。。。");
    }
}
責任編輯:武曉燕 來源: 潘志的技術(shù)筆記
相關(guān)推薦

2023-01-30 07:41:43

2021-09-15 16:20:02

Spring BootFilterJava

2024-08-12 10:13:01

2024-08-02 09:15:22

Spring捕捉格式

2024-08-01 09:10:03

2025-02-12 08:07:40

2021-05-08 08:33:00

Rocketmq日志數(shù)據(jù)源

2025-01-17 09:11:51

2022-06-04 12:25:10

解密加密過濾器

2021-03-09 13:18:53

加密解密參數(shù)

2018-11-01 13:38:51

Java中斷停止

2025-08-04 01:55:00

2025-02-27 08:30:10

2025-07-29 08:25:57

2020-08-05 08:30:25

Spring BootJavaSE代碼

2017-02-23 15:37:44

OptionObject容器

2016-05-09 10:41:03

算法分析開發(fā)

2018-01-11 15:31:39

命令Linux關(guān)機

2024-12-03 10:59:36

2017-07-10 13:09:45

前端Flexbox
點贊
收藏

51CTO技術(shù)棧公眾號

9999在线视频| 国产黄色片网站| 久久av资源| 欧美日韩综合不卡| 在线国产伦理一区| 国精品人妻无码一区二区三区喝尿 | 色婷婷亚洲综合| 一级做a爰片久久| 亚洲精品国产手机| 日韩精品一区第一页| 久热在线中文字幕色999舞| 亚洲一区二区三区四区av| 欧美羞羞视频| 亚洲美女视频在线观看| 蜜桃在线一区二区三区精品| 91尤物国产福利在线观看| 亚洲天堂成人| 久久精品欧美视频| 亚洲熟妇一区二区三区| 96sao在线精品免费视频| 在线观看欧美黄色| 全黄性性激高免费视频| 精品美女在线观看视频在线观看| 97久久超碰国产精品| 国产乱肥老妇国产一区二 | 国产日韩在线精品av| 日韩三级av在线| 88国产精品视频一区二区三区| 日韩成人在线视频网站| 绯色av蜜臀vs少妇| 香蕉成人影院| 欧美视频免费在线| 天堂8在线天堂资源bt| 日本电影全部在线观看网站视频| 91丨九色丨国产丨porny| 亚洲第一福利网| 91精品无人成人www| 美女在线视频免费| 亚洲最大的成人av| 经典三级在线视频| 日本高清视频在线观看| 久久精品欧美一区二区三区不卡| 国产精品视频入口| h片在线免费看| 久久超碰97人人做人人爱| 国产成人免费av| 成人毛片18女人毛片| 欧美日韩国产探花| 不卡av电影院| 一区二区国产精品精华液| 日韩欧美精品综合| 中文字幕精品在线视频| 波多野结衣一二三四区| 欧美日韩精品在线一区| 亚洲欧洲自拍偷拍| www.av欧美| 九九热精品视频在线观看| 日韩av在线免费播放| 国产性猛交96| 精品资源在线| 日韩电影中文 亚洲精品乱码 | 久久中文字幕电影| 久久手机视频| 精品无人乱码| 久久91精品久久久久久秒播| 国产精品久久久久77777| 无码人妻av一区二区三区波多野 | 欧美日韩国产成人| 顶臀精品视频www| 午夜精品亚洲| 久久男人资源视频| 99热国产在线观看| 久久性天堂网| 国产精品视频自拍| 91在线观看喷潮| 高清久久久久久| 国产一区二区免费在线观看| 污视频软件在线观看| 久久久三级国产网站| 久久久久国产精品视频| 欧美高清成人| 亚洲视频综合在线| 激情六月天婷婷| 欧美videossex| 黑人巨大精品欧美一区二区三区 | 亚洲福利av在线| 国产在线观看a视频| 亚洲图片欧美色图| 久久久久久香蕉| 免费高清视频在线一区| 欧美美女bb生活片| 久久久久久久久久久久国产精品| 思热99re视热频这里只精品| 伊人久久久久久久久久久久久| 美女视频久久久| 日韩一级不卡| 国产精品影片在线观看 | 精品一区二区三区三区| 免费91在线观看| 国产精品二区影院| 国产精品av在线| 国产精品探花视频| 久久综合国产精品| 超碰在线免费观看97| 欧亚av在线| 欧美一级电影网站| 亚洲国产无码精品| 欧美在线播放| 国产精品91久久久| 国产1区在线观看| 欧美国产精品v| 国产婷婷一区二区三区| 色999韩欧美国产综合俺来也| 亚洲高清不卡av| 欧美一级特黄高清视频| 久久大逼视频| 国产成人精品一区二区三区福利| jzzjzzjzz亚洲成熟少妇| 亚洲高清视频的网址| 三上悠亚在线一区二区| 亚洲区小说区图片区qvod按摩| 欧美成人精品在线| 中文天堂在线视频| 91视频精品在这里| av一区二区三区免费观看| 韩国精品视频在线观看| 亚洲人成电影网站| 狠狠躁夜夜躁人人爽天天高潮| 精品一区二区三区在线观看| 日韩国产欧美精品| 天堂av在线| 亚洲高清av在线| 久久综合成人网| 国产一区不卡视频| 一区精品视频| 成人影院在线免费观看| 亚洲免费精彩视频| 你懂的国产视频| www.av亚洲| 激情小视频网站| 嫩呦国产一区二区三区av| 少妇高潮 亚洲精品| 日韩欧美在线观看免费| 久久成人免费电影| 精品国产一区二区三区四| 国产高清不卡二三区| 五月天色婷婷综合| 国产原创一区| 丝袜美腿亚洲一区二区| 18国产免费视频| 国产亚洲美州欧州综合国| 国产亚洲精品网站| 一区二区三区韩国免费中文网站| 欧美亚洲免费电影| 欧洲成人av| 一本久道久久综合中文字幕| 97超碰在线免费观看| 亚洲综合三区| 水蜜桃一区二区三区| 肉色欧美久久久久久久免费看| 国产视频精品一区二区三区| 日韩精品在线观看免费| 久久婷婷成人综合色| 国产a级片免费观看| 国产探花一区| 国产精品高清在线| 又爽又大又黄a级毛片在线视频| 欧美片网站yy| 人妻久久一区二区| 成人美女在线视频| 每日在线更新av| 激情五月综合网| 成人av在线网址| 亚洲天堂狠狠干| 日韩理论片网站| 国产成人精品一区二区三区在线观看 | 性爱在线免费视频| 精品一区二区三区免费观看| 四虎精品欧美一区二区免费| 激情亚洲另类图片区小说区| 国产精品69久久| 成人av黄色| 亚洲成人免费在线视频| 99精品人妻国产毛片| 国产精品久久久久四虎| 欧美午夜精品一区二区| 久久久精品午夜少妇| 免费成人深夜夜行网站视频| 欧美日韩导航| 国产精品视频yy9099| 五月花成人网| 亚洲欧美中文日韩在线| 国产精品久久久久久在线| 亚洲高清一区二区三区| 国产传媒在线看| 成人夜色视频网站在线观看| 三年中国国语在线播放免费| 欧美 日韩 国产精品免费观看| 蜜桃传媒视频麻豆一区| 成人精品在线| 韩国美女主播一区| av在线播放网| 日韩av在线网页| 97视频免费在线| 欧美日韩亚洲系列| 欧产日产国产v| 国产亚洲精品bt天堂精选| 亚洲妇女无套内射精| 久久午夜精品一区二区| 日本男女交配视频| 四虎成人av| 蜜桃传媒视频第一区入口在线看| 视频精品二区| 国产精品视频不卡| 日本黄色免费在线| 久久久伊人欧美| 粗大黑人巨茎大战欧美成人| 亚洲社区在线观看| 天堂av手机版| 日韩精品一区二区三区视频播放 | 国产成人精品www牛牛影视| 成年人网站大全| 在线电影一区| 蜜臀av.com| 99精品在线观看| 日韩欧美在线一区二区| 色狼人综合干| 国产精品视频福利| 亚洲精品在线a| 91网站免费看| 日韩一级特黄| 国产精品视频资源| 成人在线观看免费视频| 国产成人avxxxxx在线看| av电影免费在线看| 欧美成人合集magnet| 快射av在线播放一区| 日韩在线不卡视频| 欧美极品视频| 日韩中文第一页| 在线视频91p| 最近2019中文免费高清视频观看www99| 毛片在线播放网站| 亚洲毛片一区二区| 六十路在线观看| 亚洲欧洲一区二区三区久久| 水中色av综合| 亚洲精品网址在线观看| 日韩美女一级视频| 亚洲美女性视频| 精品福利视频导航大全| 国产一区二区三区欧美| 国产毛片在线看| 亚洲午夜色婷婷在线| 青春有你2免费观看完整版在线播放高清 | 欧美手机视频| 日韩片电影在线免费观看| 欧美三级三级| 亚洲天堂电影网| 亚洲欧洲日韩| www.av毛片| 每日更新成人在线视频| 91小视频网站| 国产一区二区不卡在线| 特种兵之深入敌后| 不卡的av电影| 亚洲精品成人无码| 国产精品美女久久久久久久久| 亚洲熟女毛茸茸| 亚洲一区在线观看免费 | 国产日韩精品视频一区二区三区 | 精品一区二区三区四| 午夜电影一区二区三区| 免费的毛片视频| 在线不卡中文字幕播放| 亚洲国产www| 亚洲男人天堂古典| 麻豆传媒视频在线观看免费| 欧美国产亚洲精品久久久8v| 丝袜诱惑一区二区| 国产精品一区二区三区免费视频| 日韩在线视频一区二区三区| 久草一区二区| 久久人体视频| 国产一线二线三线女| 日韩电影一二三区| 男男受被啪到高潮自述| 久久综合五月天婷婷伊人| 欧美88888| 精品福利在线看| 96亚洲精品久久久蜜桃| 亚洲国产美女久久久久| 98在线视频| 97国产一区二区精品久久呦| 国模私拍国内精品国内av| 国产视频99| 99久久99久久精品国产片桃花| 无码粉嫩虎白一线天在线观看 | 色哟哟无码精品一区二区三区| 91免费视频网址| 91插插插插插插| 色先锋aa成人| 亚洲第一视频在线播放| 中文字幕9999| 这里有精品可以观看| 成人免费黄色网| 一呦二呦三呦国产精品| 国产肉体ⅹxxx137大胆| 麻豆国产一区二区| 亚洲欧美色图视频| 一区二区三区在线影院| 中文字幕一区二区三区人妻四季 | 香蕉网在线播放| 亚洲综合在线观看视频| 6—12呦国产精品| 亚洲欧美精品伊人久久| 黑人精品视频| 91亚洲国产成人精品性色| 国产精品片aa在线观看| 99在线免费视频观看| 韩国av一区二区三区四区| 91精品人妻一区二区| 亚洲二区在线观看| 国产理论片在线观看| 一区二区亚洲欧洲国产日韩| 免费v片在线观看| 国产精品精品软件视频| 国产精品久久久久久影院8一贰佰 国产精品久久久久久麻豆一区软件 | 精品国产乱码| 国产乱子夫妻xx黑人xyx真爽| 成人免费黄色大片| 成年人一级黄色片| 欧美日韩成人在线| 95在线视频| 国产精品免费一区豆花| 免费一区二区三区视频导航| 男人的天堂狠狠干| 成人国产免费视频| 国产在线拍揄自揄拍| 日韩精品一区二区三区swag| 二区三区四区高清视频在线观看| 成人激情春色网| 先锋资源久久| 亚洲精品在线网址| 亚洲色欲色欲www| av高清一区二区| 久久成人在线视频| 日本一区影院| 亚洲熟妇无码av在线播放| 国产91在线|亚洲| 日本视频www| 亚洲免费伊人电影在线观看av| 小早川怜子影音先锋在线观看| 精品日本一区二区三区| 一本久道综合久久精品| 黄色短视频在线观看| 日韩欧美亚洲范冰冰与中字| 久久久久久女乱国产| 国产精品第8页| 999国产精品永久免费视频app| 天堂av2020| 亚洲精品高清在线| 免费看av毛片| 欧美一乱一性一交一视频| 一区二区三区韩国免费中文网站| 福利在线一区二区三区| 综合激情成人伊人| 欧美三级黄色大片| 91亚洲成人| 久久精品一偷一偷国产| 日韩av男人天堂| 久久都是精品| 成人激情视频在线播放| 在线国产91| 成人免费观看网址| 伊人成人在线| wwwwww日本| 欧美日韩国产天堂| 丝袜中文在线| 日本黄网免费一区二区精品| 久草精品在线观看| 九九免费精品视频| 亚洲女人被黑人巨大进入| 国产鲁鲁视频在线观看特色| 欧美性感一类影片在线播放| 久草福利在线视频| 92看片淫黄大片看国产片| 国产免费一区二区三区最新不卡| 国产亚洲精品中文字幕| 亚洲最新av网站| 久久久久久久国产| 精品亚洲成人| 国产成人精品一区二区三区在线观看 | 无码精品一区二区三区在线播放| 91官网在线免费观看| 在线中文字幕电影| 日本一区二区三区四区高清视频| 久久99精品一区二区三区| 日本高清www免费视频| 色999日韩欧美国产|