Spring Boot实现定时任务调度

在业务系统中,定时任务是非常常见的需求,例如定时对订单状态进行更新、定时生成销售报表、自动化库存管理等。Spring Boot 提供了非常方便的定时任务调度功能,并且结合线程池技术,我们可以高效地执行多个定时任务,保证系统的扩展性和高可用性。
本文将深入探讨如何使用 Spring Boot 实现定时任务调度,特别是结合线程池技术,确保多个任务能够并发安全地执行。此外,我们还将展示如何利用 cron 表达式灵活定义定时任务的触发时间,提供详细的示例以及电商交易系统中的实际应用。


1. 定时任务调度的必要性

在电商交易系统中,定时任务的应用场景非常广泛,包括但不限于以下几种:

  1. 订单状态更新:定时检测用户的支付状态,超时未支付的订单自动取消。
  2. 自动清理任务:定期清理过期的购物车信息或未完成的订单。
  3. 库存管理:定期检查库存状态,生成库存预警。
  4. 生成报表:每天、每周或每月定时生成销售报表,发送给管理人员。

为了应对这些任务,系统需要一个可靠的定时任务调度器,并且在多任务并发执行时,必须保证系统的性能和稳定性。这就需要引入线程池技术来控制并发任务的执行。


2. Spring Boot 定时任务基础

Spring Boot 提供了非常简便的定时任务支持。通过 @EnableScheduling 注解,我们可以轻松地开启定时任务调度功能,而通过 @Scheduled 注解,我们可以指定任务的执行时间和频率。

2.1 启用定时任务

首先,我们需要在 Spring Boot 应用的主类上添加 @EnableScheduling 注解,启用定时任务调度。

package com.example.ecommerce;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;@SpringBootApplication
@EnableScheduling
public class EcommerceApplication {public static void main(String[] args) {SpringApplication.run(EcommerceApplication.class, args);}
}

2.2 使用 @Scheduled 注解

@Scheduled 注解可以定义任务的执行时间。它支持多种形式的定时表达式,其中最灵活的方式是使用 cron 表达式。

package com.example.ecommerce.task;import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;@Component
public class OrderStatusCheckTask {/*** 每隔1分钟检查一次订单状态*/@Scheduled(cron = "0 */1 * * * ?")public void checkOrderStatus() {System.out.println("执行定时任务:检查订单状态");// 订单状态检查逻辑}
}

上面的示例中,checkOrderStatus() 方法每隔1分钟执行一次,cron 表达式 0 */1 * * * ? 表示每分钟的第0秒执行一次。


3. 结合线程池技术优化定时任务

Spring Boot 的定时任务调度默认是串行执行的,也就是说,如果一个任务没有执行完毕,其他定时任务将无法开始。对于电商交易系统这样复杂的场景,多任务并发执行是非常有必要的,因此我们需要结合线程池来优化定时任务的执行。

3.1 启用异步线程池

Spring 提供了 @EnableAsync 注解用于启用异步任务支持,我们可以结合线程池让多个定时任务并发执行。

首先,在配置类中启用异步支持,并配置一个自定义线程池。

package com.example.ecommerce.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;@Configuration
@EnableAsync
public class TaskSchedulerConfig {@Beanpublic ThreadPoolTaskScheduler taskScheduler() {ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();scheduler.setPoolSize(10); // 线程池大小scheduler.setThreadNamePrefix("TaskScheduler-"); // 线程名称前缀scheduler.setAwaitTerminationSeconds(60); // 等待所有任务完成的最大时间scheduler.setWaitForTasksToCompleteOnShutdown(true); // 在关闭时等待任务完成return scheduler;}
}

在这里,我们定义了一个 ThreadPoolTaskScheduler,该线程池用于处理定时任务。线程池的大小设置为 10,表示最多可以同时执行 10 个定时任务。你可以根据系统的实际负载和需求调整线程池的大小。

3.2 使用线程池并发执行定时任务

接下来,我们将前面的 OrderStatusCheckTask 定时任务与线程池结合,让它在多线程环境中执行。

package com.example.ecommerce.task;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;@Component
public class OrderStatusCheckTask {@Autowiredprivate ThreadPoolTaskScheduler taskScheduler;/*** 每隔1分钟检查一次订单状态*/@Scheduled(cron = "0 */1 * * * ?")public void checkOrderStatus() {taskScheduler.submit(() -> {System.out.println("执行定时任务:检查订单状态");// 订单状态检查逻辑});}
}

在这个示例中,checkOrderStatus() 方法中的任务被提交给了我们自定义的线程池 taskScheduler,因此该任务将会并发执行,而不会影响其他定时任务的正常运行。


4. 支持动态配置定时任务

电商交易系统中,任务的执行时间可能需要根据实际需求进行动态调整。例如,我们希望能够通过数据库或配置文件来管理定时任务的执行时间,而不是在代码中写死。为此,我们可以引入动态配置定时任务的机制。

4.1 表结构设计

我们可以通过数据库表来保存定时任务的配置信息,并允许系统在运行时加载这些配置,动态调整任务的执行时间。

任务表 scheduled_task
CREATE TABLE scheduled_task (id BIGINT PRIMARY KEY AUTO_INCREMENT,task_name VARCHAR(255) NOT NULL COMMENT '任务名称',cron_expression VARCHAR(255) NOT NULL COMMENT 'Cron 表达式',status TINYINT NOT NULL DEFAULT 1 COMMENT '任务状态: 1-启用, 0-禁用',last_run_time TIMESTAMP COMMENT '上次运行时间',created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
);

字段说明:

  • task_name:定时任务的名称。
  • cron_expression:任务的 cron 表达式。
  • status:任务的状态,1 表示启用,0 表示禁用。
  • last_run_time:任务上次运行的时间。
  • created_atupdated_at:记录任务的创建和更新时间。

4.2 动态加载任务配置

我们可以通过数据库查询定时任务的配置信息,并动态调整任务的执行时间。

package com.example.ecommerce.service;import com.example.ecommerce.model.ScheduledTask;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class DynamicTaskService {@Autowiredprivate TaskScheduler taskScheduler;@Autowiredprivate ScheduledTaskRepository taskRepository;/*** 加载所有启用的定时任务*/public void loadTasks() {List<ScheduledTask> tasks = taskRepository.findAllByStatus(1);for (ScheduledTask task : tasks) {taskScheduler.schedule(() -> executeTask(task), new CronTrigger(task.getCronExpression()));}}/*** 执行定时任务*/private void executeTask(ScheduledTask task) {System.out.println("执行任务:" + task.getTaskName());// 执行具体任务逻辑}
}

在这个服务中,我们从数据库中加载所有启用的定时任务,并通过 taskScheduler.schedule() 方法使用 cron 表达式动态调度这些任务。

4.3 定时任务的动态控制

我们还可以通过 REST 接口或者管理后台来动态控制任务的启用和禁用。通过更新数据库中的 status 字段,就可以控制任务是否执行。定时任务调度器会根据最新的配置动态调整任务的执行状态。


5. 电商交易系统中的定时任务场景示例

5.1 订单状态检查定时任务

在电商交易系统中,订单的状态管理是非常重要的。用户下单后,如果在一定时间内未支付订单,需要自动取消订单。我们可以通过定时任务来实现这个功能。

package com.example.ecommerce.task;import com.example.ecommerce.model.Order;
import com.example.ecommerce.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;@Component
public class OrderStatusCheckTask {@Autowiredprivate OrderService orderService;/*** 每隔5分钟检查一次未支付订单状态*/@Scheduled(cron = "0 */5 * * * ?")public void checkUnpaidOrders() {System.out.println("执行定时任务:检查未支付订单");List<Order> unpaidOrders = orderService.getUnpaidOrders();for (Order order : unpaidOrders) {if (order.isOverdue()) {orderService.cancelOrder(order);System.out.println("取消超时未支付订单:" + order.getId());}}}
}

通过这个定时任务,我们可以每隔 5 分钟检查一次未支付的订单,并自动取消超时未支付的订单。

5.2 库存预警定时任务

对于库存管理,电商系统可以设置一个定时任务,每天检查库存状态,并生成库存预警,提醒管理人员补充库存。

package com.example.ecommerce.task;import com.example.ecommerce.model.Product;
import com.example.ecommerce.service.InventoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;@Component
public class InventoryCheckTask {@Autowiredprivate InventoryService inventoryService;/*** 每天早上8点检查库存状态*/@Scheduled(cron = "0 0 8 * * ?")public void checkInventory() {System.out.println("执行定时任务:检查库存状态");List<Product> lowStockProducts = inventoryService.getLowStockProducts();for (Product product : lowStockProducts) {System.out.println("库存不足产品:" + product.getName());// 发送库存预警}}
}

这个任务每天早上8点执行,检查库存状态,并生成库存预警,确保电商平台的库存充足。


6. 异步和并发控制

为了避免定时任务之间互相影响,或者由于单个任务执行过长导致的阻塞,我们可以将每个定时任务放到线程池中异步执行,从而提高任务的执行效率和系统的响应能力。

通过将定时任务提交给线程池执行,即使某个任务耗时较长,也不会影响其他任务的正常执行。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/880631.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue echarts tooltip动态绑定模板,并且处理vue事件绑定

先上代码&#xff1a; tooltip: {// 这里是车辆iconshow: true,// trigger: "item",// backgroundColor: "transparent",appendToBody: true,textStyle: {color: "#ffffff" //设置文字颜色},formatter: (params) > {const TruckTooltip Vue.…

【SOP】Windows下安装Neo4j流程

Neo4j简介 Neo4j 是一个基于图形结构的 NoSQL 数据库&#xff0c;专门用于存储和管理图数据。与传统的关系型数据库不同&#xff0c;Neo4j 使用 图&#xff08;graph&#xff09;的形式来表示数据&#xff0c;其中数据点&#xff08;称为 节点&#xff09;通过 边&#xff08;…

遥感图像语义分割数据集制作(使用ArcGIS Pro)

0. 引言 图像分割就是把图像空间按照一定的要求分成一些“有意义”的区域的技术叫图像分割。一幅图像通常是由代表物体的图案与背景组成&#xff0c;简称物体与背景。若想从一幅图像中“提取”物体&#xff0c;可以设法用专门的方法标出属于该物体的点&#xff0c;如把物体上的…

WebSocket实现在线聊天室

项目实现源码&#xff1a; 前端源码 后端源码 1.常见的消息推送方式 1.1 轮询 1.1.1 轮询的概念 客户端以固定的事件间隔&#xff08;例如每秒或几分钟&#xff09;向服务器发送HTTP请求&#xff0c;服务器收到请求后&#xff0c;处理请求并返回数据给客户端 轮询具体实现htt…

计算机毕业设计之:宠物服务APP的设计与实现(源码+文档+讲解)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

如何把PDF样本册转换为网址链接

​随着互联网的普及&#xff0c;将纸质或PDF格式的样本册转化为网址链接&#xff0c;以便于在线浏览和分享&#xff0c;变得越来越重要。本文将为您详细讲解如何将PDF样本册转换为网址链接&#xff0c;让您轻松实现线上展示和分享。 一、了解PDF样本册与网址链接 1. PDF样本册…

游戏账号系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;卖家管理&#xff0c;游戏类别管理&#xff0c;游戏账号管理&#xff0c;站内联系管理&#xff0c;交易订单管理&#xff0c;帐号退货管理 微信端账号功能包括&#xff1a;系统首…

多输入多输出预测 | NGO-BP北方苍鹰算法优化BP神经网络多输入多输出预测(Matlab)

多输入多输出预测 | NGO-BP北方苍鹰算法优化BP神经网络多输入多输出预测&#xff08;Matlab&#xff09; 目录 多输入多输出预测 | NGO-BP北方苍鹰算法优化BP神经网络多输入多输出预测&#xff08;Matlab&#xff09;预测效果基本介绍程序设计往期精彩参考资料 预测效果 基本介…

数据结构:树的定义及其性质

树的定义 树是一种重要的非线性数据结构&#xff0c;树作为一种逻辑结构&#xff0c;同时也是一种分层结构。具有以下两个特点&#xff1a; 1.树的根结点没有前驱&#xff0c;除根结点意外的节点只有一个前驱 2.树中所有结点都可以有0个或多个后继 树结构在多个领域都有广泛…

GDB 调试

1. wsl 环境下搭建gdb&#xff1a; 1.1安装环境&#xff1a; #安装gcc编译器 (x86 linux) $ sudo apt install gcc #检查安装版本&#xff0c;看是否成功 $ gcc -v #安装gdb编译器 (x86 linux) $ sudo apt install gdb #检查安装是否成功 $ gdb 1.2 编写自己的程序&…

刷题学习日记 (1) - SWPUCTF

写这篇文章主要是想看看自己一个下午能干啥&#xff0c;不想老是浪费时间了&#xff0c;所以刷多少题我就会写多少题解&#xff0c;使用nss随机刷题&#xff0c;但是今天下午不知道为啥一刷都是SWPUCTF的。 [SWPUCTF 2021 新生赛]gift_F12 控制台ctrlf搜索flag即可&#xff0…

处理not in gzip format异常

1、为什么会触发这个异常&#xff1f; 当我们使用GZIPInputStream的read方法进行读取数据时&#xff0c;它会自动处理gzip格式的压缩数据&#xff0c;将它解析成原始的二进制数据。但是&#xff0c;如果你没有将原始数据进行gzip压缩后传入GZIPInputStream流&#xff0c;进行r…

车载诊断技术:汽车健康的守护者

一、车载诊断技术的发展历程 从最初简单的硬件设备到如今智能化、网络化的系统,车载诊断技术不断演进,为汽车安全和性能提供保障。 早期的汽车诊断检测技术处于比较原始的状态,主要依靠操作经验和主观评价。随着汽车工业的发展,车载诊断技术也经历了不同的阶段。20 世纪初…

视频融合共享平台LntonAIServer视频智能分析抖动检测算法和过亮过暗检测算法

LntonAIServer作为一款智能视频监控平台&#xff0c;集成了多种先进的视频质量诊断功能&#xff0c;其中包括抖动检测和过暗检测算法。这些算法对于提升视频监控系统的稳定性和图像质量具有重要意义。 以下是对抖动检测算法和过暗检测算法的应用场景及优势的详细介绍。 一、L…

数据分析:线性回归计算嵌套的组间差异

文章目录 介绍加载依赖包导入数据数据预处理数据概览线性回归画图森林图的特点:森林图的作用:总结系统信息介绍 在统计学中,嵌套的组间差异分析是一种评估不同组别间差异的方法,尤其适用于层级结构或分组数据。通过线性回归模型,我们可以计算出各个变量对于因变量的影响,…

基于Node.js+Express+MySQL+VUE新闻网站管理系统的设计与实现

1. 引言 随着互联网技术的发展&#xff0c;人们获取信息的方式发生了巨大的变化。传统的新闻媒体逐渐向数字化、智能化方向发展。新闻推荐网站管理系统能够帮助新闻网站更好地管理和推荐新闻内容&#xff0c;提高用户体验。本文将详细介绍一个新闻推荐网站管理系统的整体设计与…

《十年国庆游,洞察中国旅游新趋势》

作者&#xff1a;侯炯 一、十年国庆旅游数据总览 过去十年&#xff0c;中国国庆旅游市场呈现出丰富的变化和强劲的发展态势。从接待游客人次来看&#xff0c;2014 年接待国内游客 4.75 亿人次&#xff0c;到 2019 年已增长至 7.82 亿人次&#xff0c;2023 年国内旅游出游人数更…

北斗三号多模对讲机TD70:公专网融合、数模一体、音视频调度,推动应急通信效能升级

随着国家对应急通信和精准定位技术的重视程度不断提高&#xff0c;相关技术和设备的研发与应用也得到了迅猛发展。特别是在边防巡逻、林业巡防、海上作业等领域&#xff0c;通信设备的可靠性和功能性直接关系到人员的生命安全和任务的成功完成。 近年来&#xff0c;我国政府高度…

深度学习500问——Chapter17:模型压缩及移动端部署(1)

文章目录 17.1 模型压缩理解 17.2 为什么需要模型压缩和加速 17.3 模型压缩的必要性及可行性 17.4 目前有哪些深度学习模型压缩方法 17.4.1 前段压缩和后端压缩对比 17.4.2 网络剪枝 17.4.3 典型剪枝方法对比 17.4.4. 网络蒸馏 17.4.5 前端压缩 17.4.6 后端压缩 深度神经网络在…

A股收复3000点!外资积极看涨,对冲基金净买入量创三年来新高

9月27日&#xff0c;A股开盘后跳空上涨&#xff0c;连续四天的大幅上涨&#xff0c;9月26日&#xff0c;上证指数收复3000点大关&#xff0c;让一些温州股民感到兴奋不已&#xff0c;一些炒股群里沸腾了。但对于行情走势&#xff0c;股民们产生了分歧&#xff0c;有人是逢高减仓…