成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

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

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

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

運行效果:

圖片圖片

圖片圖片

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

項目結構

為了實現(xiàn)我們的目標,我們的項目結構將包含以下部分:

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

項目依賴配置(pom.xml)

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

<?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)

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

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

server:
  port: 8080
  
spring:
  task:
    scheduling:
      pool:
        size: 5  # 配置線程池大小,設為5個線程
      shutdown:
        await-termination: true  # 在應用關閉時等待所有任務完成
        await-termination-period: 30s  # 等待時間設置為30秒

這里我們設置了一個調度池,并配置了任務關閉時的等待策略,以確保任務能夠優(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;

}

定時任務的實現(xiàn)

@Scheduled 注解的詳細用法

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

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

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

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

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

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

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

  1. 使用 Cron 表達式:

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

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

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

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("固定速率任務執(zhí)行時間: {}", dateTimeFormatter.format(LocalDateTime.now()));
    }

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

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

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

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

任務管理器的實現(xiàn)

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

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

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

控制器的實現(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)); // 初始延遲任務,10秒后執(zhí)行
            cronExpressionTask = taskScheduler.schedule(scheduledTaskBean::scheduleTaskWithCronExpression,
                new CronTrigger("0 0/1 * * * ?")); // Cron表達式任務
            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;
    }
}

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

啟動應用程序

在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);
	}

}

在啟動類中,我們啟用了定時任務調度功能。

視圖控制器

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>任務管理</title>
    <link  rel="stylesheet">
</head>
<body>
<div class="container">
    <h1 class="mt-5">定時任務管理</h1>
    <div class="mt-3">
        <button id="startBtn" class="btn btn-danger">啟動任務</button>
        <button id="stopBtn" class="btn btn-secondary" disabled>停止任務</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);
            }
        }

        // 頁面加載時獲取任務狀態(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>

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

運行與測試

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

總結

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

責任編輯:武曉燕 來源: 路條編程
相關推薦

2024-07-31 14:03:00

Spring定時任務管理

2024-09-04 11:16:44

端口Spring配置類

2024-08-30 11:28:09

2024-09-02 08:17:18

2019-02-20 15:52:50

技術開發(fā)代碼

2017-08-16 16:41:04

JavaSpringBoot定時任務

2024-02-28 09:54:07

線程池配置

2024-09-20 05:49:04

SpringBoot后端

2025-02-24 16:00:00

SpringBoot定時任務開發(fā)

2024-09-06 10:05:47

SpELSpring權限

2025-04-21 02:20:00

2021-04-11 07:48:42

定時任務Linux jdk

2009-10-28 10:05:29

Ubuntucrontab定時任務

2012-02-07 13:31:14

SpringJava

2010-03-10 15:47:58

crontab定時任務

2023-01-04 09:23:58

2024-09-09 08:11:12

2024-08-09 08:46:00

Springjar 包YAML

2024-10-28 08:32:22

統(tǒng)一接口響應SpringBoot響應框架

2023-10-31 12:42:00

Spring動態(tài)增刪啟停
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日日操夜夜操天天操 | 夜夜av| aaa精品 | 中文二区| 久国久产久精永久网页 | 夜夜av | 成人av高清在线观看 | 91精品久久久久久久久久入口 | 亚洲精品国产一区 | 久久精品成人 | 毛片免费视频 | 天天干狠狠 | 亚洲中字在线 | 亚洲精彩免费视频 | 国产一区二区免费 | 国产黑丝av | 久久久久国产一区二区 | 久久久久国产精品一区 | 亚洲麻豆 | 一级片aaa | 亚洲精品欧美一区二区三区 | 色接久久 | 免费观看一级特黄欧美大片 | 日韩精品久久一区 | 亚洲大片在线观看 | 国产成人精品一区二区三区在线 | 日本一区二区不卡 | www.久久久久久久久久久 | 亚洲电影第1页 | 欧美在线国产精品 | 日韩久草 | 国外成人在线视频网站 | 精品麻豆剧传媒av国产九九九 | 国产成人99久久亚洲综合精品 | 国产精品美女久久久久久免费 | 欧美日韩精品久久久免费观看 | 超碰在线播 | 婷婷激情综合 | 日韩视频一区二区 | 99re热精品视频国产免费 | 成人区精品 |