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

SpringBoot3.3 優(yōu)雅停止/重啟定時任務(wù)功能太贊了!

開發(fā) 前端
在本文中,我們通過Yaml?屬性配置了自定義線程池,詳細(xì)介紹了@Scheduled注解的多種用法,并實(shí)現(xiàn)了一個能夠優(yōu)雅地啟動和停止定時任務(wù)的管理系統(tǒng)。

在現(xiàn)代Java應(yīng)用開發(fā)中,定時任務(wù)是非常常見的功能。無論是定期備份、數(shù)據(jù)清理,還是定期發(fā)送通知,定時任務(wù)都能發(fā)揮至關(guān)重要的作用。然而,在一個復(fù)雜的應(yīng)用程序中,如何優(yōu)雅地管理這些定時任務(wù)的啟動與停止,尤其是在不影響系統(tǒng)正常運(yùn)行的情況下,顯得尤為重要。

Spring Boot 提供了強(qiáng)大的任務(wù)調(diào)度支持,通過@Scheduled注解可以輕松地創(chuàng)建定時任務(wù),并且可以通過配置來靈活地管理這些任務(wù)的執(zhí)行環(huán)境。在本文中,我們將深入探討如何通過Yaml屬性配置自定義線程池,并詳細(xì)介紹如何使用@Scheduled注解實(shí)現(xiàn)多樣化的定時任務(wù)。此外,我們還會探討如何優(yōu)雅地停止和重啟這些任務(wù),確保系統(tǒng)的穩(wěn)定性和任務(wù)的靈活性。

運(yùn)行效果:

圖片圖片

圖片圖片

若想獲取項(xiàng)目完整代碼以及其他文章的項(xiàng)目源碼,且在代碼編寫時遇到問題需要咨詢交流,歡迎加入下方的知識星球。

項(xiàng)目結(jié)構(gòu)

為了實(shí)現(xiàn)我們的目標(biāo),我們的項(xiàng)目結(jié)構(gòu)將包含以下部分:

  1. Spring Boot主應(yīng)用程序:啟動Spring Boot應(yīng)用,并注冊定時任務(wù)。
  2. 定時任務(wù)實(shí)現(xiàn):定義定時任務(wù)的邏輯。
  3. 任務(wù)管理器:提供控制定時任務(wù)啟停的方法。
  4. 前端頁面:提供簡潔的前端頁面,允許用戶通過頁面來啟停定時任務(wù)。

項(xiàng)目依賴配置(pom.xml)

首先,我們需要在pom.xml文件中添加相關(guān)的依賴:

<?xml versinotallow="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.3.3</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.icoderoad</groupId>
	<artifactId>taskmanager</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>taskmanager</name>
	<description>Demo project for Spring Boot</description>
	
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		
		<!-- Thymeleaf template engine -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        
        <!-- Spring Boot Web Starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Lombok for reducing boilerplate code -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

配置文件(application.yaml)

在任務(wù)調(diào)度中,線程池的配置是影響任務(wù)執(zhí)行效率和可靠性的重要因素。默認(rèn)情況下,Spring Boot 為調(diào)度任務(wù)提供了一個單線程的執(zhí)行器,但對于復(fù)雜的業(yè)務(wù)場景,我們往往需要一個更高效的多線程池來管理多個任務(wù)的并發(fā)執(zhí)行。通過在application.yaml中配置ThreadPoolTaskScheduler,我們可以自定義線程池的大小以及關(guān)閉策略。

接下來,在src/main/resources/application.yaml中添加以下配置:

server:
  port: 8080
  
spring:
  task:
    scheduling:
      pool:
        size: 5  # 配置線程池大小,設(shè)為5個線程
      shutdown:
        await-termination: true  # 在應(yīng)用關(guān)閉時等待所有任務(wù)完成
        await-termination-period: 30s  # 等待時間設(shè)置為30秒

這里我們設(shè)置了一個調(diào)度池,并配置了任務(wù)關(guān)閉時的等待策略,以確保任務(wù)能夠優(yōu)雅停止。

創(chuàng)建 TaskSchedulerProperties 配置類

創(chuàng)建一個配置類來綁定 application.yml 中的屬性:

package com.icoderoad.taskmanager.properties;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import lombok.Data;

@Data
@Component
@ConfigurationProperties(prefix = "spring.task.scheduling.pool")
public class TaskSchedulerProperties {

    private int size;

}

定時任務(wù)的實(shí)現(xiàn)

@Scheduled 注解的詳細(xì)用法

@Scheduled注解是Spring中的一個強(qiáng)大工具,用于定義各種類型的定時任務(wù)。它支持多種觸發(fā)方式,包括固定速率(fixedRate)、固定延遲(fixedDelay)、和Cron表達(dá)式等,能夠滿足幾乎所有常見的定時任務(wù)需求。

  1. 固定速率執(zhí)行(fixedRate):

@Scheduled(fixedRate = 5000) 表示任務(wù)將在上一次任務(wù)開始執(zhí)行后,5秒鐘再執(zhí)行下一次任務(wù)。即任務(wù)之間的間隔時間固定為5秒。

  1. 固定延遲執(zhí)行(fixedDelay):

@Scheduled(fixedDelay = 5000) 表示任務(wù)將在上一次任務(wù)執(zhí)行結(jié)束后,等待5秒鐘再執(zhí)行下一次任務(wù)。與fixedRate不同的是,fixedDelay計算的是任務(wù)結(jié)束與下一次任務(wù)開始之間的間隔。

  1. 首次延遲執(zhí)行(initialDelay):

@Scheduled(initialDelay = 10000, fixedRate = 5000) 表示任務(wù)將在應(yīng)用啟動后10秒鐘開始第一次執(zhí)行,隨后每隔5秒執(zhí)行一次。

  1. 使用 Cron 表達(dá)式:

@Scheduled(cron = "0 0/1 * * * ?") 表示任務(wù)將在每分鐘的第0秒執(zhí)行一次。Cron表達(dá)式是一種非常靈活的時間表達(dá)方式,允許指定任務(wù)的精確執(zhí)行時間,例如每小時的整點(diǎn)、每月的特定日期等。

通過以上的配置與注解使用方法,我們可以靈活地在Spring Boot應(yīng)用中創(chuàng)建各種類型的定時任務(wù),同時結(jié)合自定義線程池配置,確保任務(wù)的并發(fā)執(zhí)行效率和系統(tǒng)的穩(wěn)定性。

在src/main/java/com/icoderoad/taskmanager/task/目錄下創(chuàng)建MyScheduledTask.java類,用于定義我們的定時任務(wù)。

package com.icoderoad.taskmanager.task;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class ScheduledTask {

    private static final Logger logger = LoggerFactory.getLogger(ScheduledTask.class);
    private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    public void scheduleTaskWithFixedRate() {
        logger.info("固定速率任務(wù)執(zhí)行時間: {}", dateTimeFormatter.format(LocalDateTime.now()));
    }

    public void scheduleTaskWithFixedDelay() {
        logger.info("固定延遲任務(wù)執(zhí)行時間: {}", dateTimeFormatter.format(LocalDateTime.now()));
    }

    public void scheduleTaskWithInitialDelay() {
        logger.info("首次延遲任務(wù)執(zhí)行時間: {}", dateTimeFormatter.format(LocalDateTime.now()));
    }

    public void scheduleTaskWithCronExpression() {
        logger.info("Cron表達(dá)式任務(wù)執(zhí)行時間: {}", dateTimeFormatter.format(LocalDateTime.now()));
    }
}

在這個簡單的示例中,performTask()方法會每隔5秒鐘執(zhí)行一次,并輸出當(dāng)前的時間戳。

任務(wù)管理器的實(shí)現(xiàn)

為了控制定時任務(wù)的啟動和停止,我們可以創(chuàng)建一個任務(wù)管理器類。

在src/main/java/com/icoderoad/taskmanager/service/目錄下創(chuàng)建TaskSchedulerManager.java類:

此類提供了停止和重啟任務(wù)的功能。

控制器的實(shí)現(xiàn)

在src/main/java/com/icoderoad/taskmanager/controller/目錄下創(chuàng)建TaskController.java類:

package com.icoderoad.taskmanager.service;

import java.util.Date;
import java.util.concurrent.ScheduledFuture;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Service;

import com.icoderoad.taskmanager.properties.TaskSchedulerProperties;
import com.icoderoad.taskmanager.task.ScheduledTask;

@Service
public class TaskSchedulerManager {

    private final TaskScheduler taskScheduler;
    private final TaskSchedulerProperties taskSchedulerProperties;
    private ScheduledFuture<?> fixedDelayTask;
    private ScheduledFuture<?> initialDelayTask;
    private ScheduledFuture<?> cronExpressionTask;
    private boolean isTaskRunning = false;

    @Autowired
    private ScheduledTask scheduledTaskBean;

    @Autowired
    public TaskSchedulerManager(TaskScheduler taskScheduler, TaskSchedulerProperties taskSchedulerProperties) {
        this.taskScheduler = taskScheduler;
        this.taskSchedulerProperties = taskSchedulerProperties;
        initializeScheduler();
    }

    private void initializeScheduler() {
        if (taskScheduler instanceof ThreadPoolTaskScheduler) {
            ((ThreadPoolTaskScheduler) taskScheduler).setPoolSize(taskSchedulerProperties.getSize());
        }
    }

    public void startTask() {
        if (!isTaskRunning) {
            fixedDelayTask = taskScheduler.scheduleWithFixedDelay(scheduledTaskBean::scheduleTaskWithFixedDelay, 5000);
            initialDelayTask = taskScheduler.schedule(() -> {
                scheduledTaskBean.scheduleTaskWithInitialDelay();
            }, new Date(System.currentTimeMillis() + 10000)); // 初始延遲任務(wù),10秒后執(zhí)行
            cronExpressionTask = taskScheduler.schedule(scheduledTaskBean::scheduleTaskWithCronExpression,
                new CronTrigger("0 0/1 * * * ?")); // Cron表達(dá)式任務(wù)
            isTaskRunning = true;
        }
    }

    public void stopTask() {
        if (isTaskRunning) {
            if (fixedDelayTask != null) {
                fixedDelayTask.cancel(true);
            }
            if (initialDelayTask != null) {
                initialDelayTask.cancel(true);
            }
            if (cronExpressionTask != null) {
                cronExpressionTask.cancel(true);
            }
            isTaskRunning = false;
        }
    }

    public boolean isTaskRunning() {
        return isTaskRunning;
    }
}

通過這個控制器,我們能夠處理來自前端頁面的請求,停止或重啟定時任務(wù)。

啟動應(yīng)用程序

在src/main/java/com/icoderoad/taskmanager/目錄下創(chuàng)建TaskManagerApplication.java`類:

package com.icoderoad.taskmanager;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class TaskmanagerApplication {

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

}

在啟動類中,我們啟用了定時任務(wù)調(diào)度功能。

視圖控制器

package com.icoderoad.taskmanager.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class IndexController {

    @GetMapping("/")
    public String index() {
        return "index";
    }
}

前端頁面(Thymeleaf + Bootstrap)

在src/main/resources/templates/目錄下創(chuàng)建一個簡單的HTML文件index.html:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>任務(wù)管理</title>
    <link  rel="stylesheet">
</head>
<body>
<div class="container">
    <h1 class="mt-5">定時任務(wù)管理</h1>
    <div class="mt-3">
        <button id="startBtn" class="btn btn-danger">啟動任務(wù)</button>
        <button id="stopBtn" class="btn btn-secondary" disabled>停止任務(wù)</button>
    </div>
    <div id="messageBox" class="alert mt-3" role="alert" style="display:none;"></div>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
<script>
    $(document).ready(function() {
        function showMessage(type, message) {
            const messageBox = $('#messageBox');
            messageBox.removeClass('alert-success alert-danger').addClass('alert-' + type);
            messageBox.text(message);
            messageBox.show();
        }

        function updateButtonStates(isRunning) {
            if (isRunning) {
                $('#startBtn').removeClass('btn-danger').addClass('btn-secondary').prop('disabled', true);
                $('#stopBtn').removeClass('btn-secondary').addClass('btn-danger').prop('disabled', false);
            } else {
                $('#startBtn').removeClass('btn-secondary').addClass('btn-danger').prop('disabled', false);
                $('#stopBtn').removeClass('btn-danger').addClass('btn-secondary').prop('disabled', true);
            }
        }

        // 頁面加載時獲取任務(wù)狀態(tài)并更新按鈕狀態(tài)
        $.get("/task/status", function(response) {
            updateButtonStates(response.isRunning);
        });

        $('#startBtn').click(function() {
            $.post("/task/start-task", function(response) {
                if (response.status === 'success') {
                    showMessage('success', response.message);
                    updateButtonStates(true);
                } else {
                    showMessage('danger', response.message);
                }
            });
        });

        $('#stopBtn').click(function() {
            $.post("/task/stop-task", function(response) {
                if (response.status === 'success') {
                    showMessage('success', response.message);
                    updateButtonStates(false);
                } else {
                    showMessage('danger', response.message);
                }
            });
        });
    });
</script>
</body>
</html>

此頁面提供了簡單的按鈕,允許用戶停止或重啟定時任務(wù)。

運(yùn)行與測試

啟動應(yīng)用程序后,打開瀏覽器訪問http://localhost:8080/taskManager,你將看到管理定時任務(wù)的界面。點(diǎn)擊“停止任務(wù)”按鈕,可以停止定時任務(wù);點(diǎn)擊“重啟任務(wù)”按鈕,則可以重新啟動定時任務(wù)。

總結(jié)

在本文中,我們通過Yaml屬性配置了自定義線程池,詳細(xì)介紹了@Scheduled注解的多種用法,并實(shí)現(xiàn)了一個能夠優(yōu)雅地啟動和停止定時任務(wù)的管理系統(tǒng)。通過這種方式,我們可以靈活地控制應(yīng)用中的定時任務(wù),提高系統(tǒng)的穩(wěn)定性和可維護(hù)性。這種設(shè)計非常適合在生產(chǎn)環(huán)境中應(yīng)用,尤其是在需要頻繁調(diào)整任務(wù)調(diào)度策略的場景下。

責(zé)任編輯:武曉燕 來源: 路條編程
相關(guān)推薦

2024-07-31 14:03:00

Spring定時任務(wù)管理

2024-09-04 11:16:44

端口Spring配置類

2024-08-30 11:28:09

2024-09-02 08:17:18

2025-02-24 16:00:00

SpringBoot定時任務(wù)開發(fā)

2024-09-20 05:49:04

SpringBoot后端

2017-08-16 16:41:04

JavaSpringBoot定時任務(wù)

2019-02-20 15:52:50

技術(shù)開發(fā)代碼

2024-02-28 09:54:07

線程池配置

2024-09-06 10:05:47

SpELSpring權(quán)限

2025-04-21 02:20:00

2021-04-11 07:48:42

定時任務(wù)Linux jdk

2009-10-28 10:05:29

Ubuntucrontab定時任務(wù)

2012-02-07 13:31:14

SpringJava

2010-03-10 15:47:58

crontab定時任務(wù)

2023-01-04 09:23:58

2024-09-09 08:11:12

2021-06-30 07:19:34

SpringBoot定時任務(wù)

2023-10-31 12:42:00

Spring動態(tài)增刪啟停

2024-11-04 16:01:01

點(diǎn)贊
收藏

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