欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Springboot如何優(yōu)雅的關(guān)閉應(yīng)用

 更新時間:2024年08月19日 09:54:55   作者:一棵星  
這篇文章主要介紹了Springboot如何優(yōu)雅的關(guān)閉應(yīng)用問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

使用Spring Boot Actuator會中斷運行中的業(yè)務(wù)嗎?

當你向 /actuator/shutdown 端點發(fā)送 POST 請求以關(guān)閉應(yīng)用時,Spring Boot Actuator 會觸發(fā)應(yīng)用的關(guān)閉操作。這意味著應(yīng)用會執(zhí)行相應(yīng)的關(guān)閉邏輯,并嘗試優(yōu)雅地停止正在運行的業(yè)務(wù)。

如果你的業(yè)務(wù)邏輯中實現(xiàn)了優(yōu)雅關(guān)閉的機制,例如捕獲了中斷信號并正確處理了中斷,那么應(yīng)用關(guān)閉時不會突然中斷運行中的業(yè)務(wù)。相反,應(yīng)用會嘗試完成當前正在執(zhí)行的任務(wù),然后安全地關(guān)閉。這種方式可以確保在關(guān)閉應(yīng)用時不會丟失數(shù)據(jù)或者導(dǎo)致不一致的狀態(tài)。

然而,如果你的業(yè)務(wù)邏輯沒有實現(xiàn)優(yōu)雅關(guān)閉的機制,或者在關(guān)閉操作中遇到了異常,那么關(guān)閉應(yīng)用時可能會導(dǎo)致正在運行的業(yè)務(wù)被中斷。這取決于應(yīng)用的具體實現(xiàn)和業(yè)務(wù)邏輯。

如何使用Spring Boot Actuator關(guān)閉應(yīng)用

1.引入Actuator包

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

2.application.yml配置

# 開發(fā)環(huán)境配置
server:
  # 服務(wù)器的HTTP端口,默認為80
  port: 80

management:
  endpoint:
    shutdown:
      enabled: true
  endpoints:
    web:
      exposure:
        include: "shutdown"
      base-path: /monitor

3.CURL 命令關(guān)閉應(yīng)用的示例

curl -X POST http://localhost:80/monitor/shutdown

4.運行截圖

使用Spring Boot Actuator關(guān)閉應(yīng)用,會終止正在運行中的程序,如果想要運行中的業(yè)務(wù)不中斷,需要自定義關(guān)閉器的關(guān)閉事件,使運行中的程序處理完成才關(guān)閉應(yīng)用。

如何自定義關(guān)閉監(jiān)聽器關(guān)閉事件優(yōu)雅的關(guān)閉應(yīng)用

本實例使用異步線程任務(wù)來模擬運行中的任務(wù)。

1.定義異步管理類

package com.angel.ocean.tool.util;

import com.angel.ocean.tool.task.CommonTask;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * 異步任務(wù)工具類
 */
@Slf4j
public class TaskExecutorUtil {

    // Task運行狀態(tài)
    public static volatile boolean isRunning = true;

    // Task運行結(jié)果Future集合
    private final static List<Future<?>> runningTasks = new ArrayList<>();

    // 線程池
    static ExecutorService executorPool = new ThreadPoolExecutor(corePoolSize(), maximumPoolSize(), 10, TimeUnit.MINUTES,
            new ArrayBlockingQueue<Runnable>(1000), new ThreadPoolExecutor.CallerRunsPolicy());

    /**
     * Task執(zhí)行
     */
    public static void executeTask(CommonTask task) {
        Future<?> future = executorPool.submit(task);
        runningTasks.add(future);
    }

    /**
     * 關(guān)閉運行中所有線程,如果任務(wù)正在執(zhí)行中,待執(zhí)行完成再中斷該線程
     */
    public static void stopAllTasks() {
        isRunning = false;
        for (Future<?> future : runningTasks) {
            try {
                boolean flag = true;
                while (flag) {
                    // 如果任務(wù)還在執(zhí)行中,就休眠100ms
                    if(!future.isDone()) {
                        Thread.sleep(100);
                    } else {
                        flag = false;
                    }
                }
            } catch (InterruptedException e) {
                // 打印異常
                log.error("TaskExecutorUtil stopAllTasks {}", e.getMessage(), e);
            } finally {
                // 中斷任務(wù)
                future.cancel(true);
            }
        }
    }

    /**
     * 關(guān)閉線程池
     */
    public static void waitForTasksToComplete() {
        // 等待所有任務(wù)完成
        executorPool.shutdown();
    }

    /**
     * 核心線程數(shù)
     */
    private static int corePoolSize() {
        return Runtime.getRuntime().availableProcessors();
    }

    /**
     * 最大線程數(shù)
     */
    private static int maximumPoolSize() {
        return Runtime.getRuntime().availableProcessors() * 2;
    }
}

2.定義監(jiān)聽 Spring 應(yīng)用的關(guān)閉事件

package com.angel.ocean.tool.event;

import com.angel.ocean.tool.util.TaskExecutorUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.stereotype.Component;

/**
 *  監(jiān)聽 Spring 應(yīng)用的關(guān)閉事件
 */
@Slf4j
@Component
public class ShutdownListener implements ApplicationListener<ContextClosedEvent> {
    @Override
    public void onApplicationEvent(ContextClosedEvent event) {

        log.info("應(yīng)用正在關(guān)閉...");

        // 中斷所有正在運行的任務(wù)
        TaskExecutorUtil.stopAllTasks();

        // 等待所有任務(wù)完成
        TaskExecutorUtil.waitForTasksToComplete();

        log.info("應(yīng)用已經(jīng)關(guān)閉...");
    }
}

3.定義異步任務(wù)Task

package com.angel.ocean.tool.runner;

import com.angel.ocean.tool.task.MyTask;
import com.angel.ocean.tool.util.TaskExecutorUtil;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class MyTaskRunner implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        // 創(chuàng)建并執(zhí)行任務(wù)
        MyTask task = new MyTask();
        TaskExecutorUtil.executeTask(task);
        System.out.println("任務(wù)已啟動...");
    }
}
package com.angel.ocean.tool.task;

import com.angel.ocean.tool.util.TaskExecutorUtil;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class MyTask extends CommonTask {
    @Override
    public void handler() {
        while (TaskExecutorUtil.isRunning) {
            log.info("本次任務(wù)開始執(zhí)行.......");
            try {
                for(int i = 0; i < 10; i++) {
                    // 模擬任務(wù)執(zhí)行時間,等待1s
                    Thread.sleep(1000);
                    log.info("i = {}", i);
                }
                log.info("本次任務(wù)執(zhí)行完成.......");
            } catch (InterruptedException e) {
                // 處理中斷請求
                Thread.currentThread().interrupt();
                log.info("任務(wù)被中斷.......");
            }
        }
    }
}
package com.angel.ocean.tool.task;

import lombok.extern.slf4j.Slf4j;

/**
 * Task抽象類
 */
@Slf4j
public abstract class CommonTask implements Runnable {

    @Override
    public void run() {
        handler();
    }

    public void handler() {

    }
}

4.驗證截圖

可以看出,在Task運行中時執(zhí)行了關(guān)閉任務(wù)操作,但是待Task業(yè)務(wù)執(zhí)行完成了才關(guān)閉了應(yīng)用。

總結(jié)

本文介紹了如何通過使用Spring Boot Actuator關(guān)閉應(yīng)用,并自定義關(guān)閉監(jiān)聽器關(guān)閉事件,優(yōu)雅的關(guān)閉應(yīng)用,給出了如何優(yōu)雅的關(guān)閉異步任務(wù)的實例,有興趣的小伙伴可以參考。

相關(guān)文章

  • spring.datasource.schema配置詳解

    spring.datasource.schema配置詳解

    本文主要介紹了spring.datasource.schema配置,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • 了解Java多線程的可見性與有序性

    了解Java多線程的可見性與有序性

    這篇文章主要介紹了了解Java多線程的可見性與有序性,在Java內(nèi)存模型中,允許編譯器和處理器對指令進行重排序,但是重排序過程不會影響到單線程程序的執(zhí)行,卻會影響到多線程并發(fā)執(zhí)行的正確性。,需要的朋友可以參考下
    2019-06-06
  • 使用Springboot+poi上傳并處理百萬級數(shù)據(jù)EXCEL

    使用Springboot+poi上傳并處理百萬級數(shù)據(jù)EXCEL

    這篇文章主要介紹了使用Springboot+poi上傳并處理百萬級數(shù)據(jù)EXCEL,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Maven的常用命令總結(jié)大全

    Maven的常用命令總結(jié)大全

    這篇文章主要給大家介紹了Maven常用命令總結(jié)的相關(guān)資料,maven最大的作用就是用于對項目中jar包依賴的統(tǒng)一管理,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2023-12-12
  • MybatisPlus自定義Sql實現(xiàn)多表查詢的示例

    MybatisPlus自定義Sql實現(xiàn)多表查詢的示例

    這篇文章主要介紹了MybatisPlus自定義Sql實現(xiàn)多表查詢的示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • spring boot高并發(fā)下耗時操作的實現(xiàn)方法

    spring boot高并發(fā)下耗時操作的實現(xiàn)方法

    這篇文章主要給大家介紹了關(guān)于spring boot高并發(fā)下耗時操作的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用spring boot具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • 一文秒懂java到底是值傳遞還是引用傳遞

    一文秒懂java到底是值傳遞還是引用傳遞

    這篇文章主要介紹了java到底是值傳遞還是引用傳遞的相關(guān)知識,本文通過幾個例子給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • Java實現(xiàn)消息轟炸的方法 附帶源碼

    Java實現(xiàn)消息轟炸的方法 附帶源碼

    這篇文章主要介紹了Java實現(xiàn)消息轟炸的方法 附帶源碼,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • Java總結(jié)篇系列:Java泛型詳解

    Java總結(jié)篇系列:Java泛型詳解

    下面小編就為大家?guī)硪黄狫ava總結(jié)篇系列:Java泛型詳解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-09-09
  • 如何解決@Valid對象嵌套List對象校驗無效問題

    如何解決@Valid對象嵌套List對象校驗無效問題

    這篇文章主要介紹了如何解決@Valid對象嵌套List對象校驗無效問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07

最新評論