Spring Boot 2.x基础教程:使用@Scheduled实现定时任务

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: Spring Boot 2.x基础教程:使用@Scheduled实现定时任务

我们在编写Spring Boot应用中经常会遇到这样的场景,比如:我需要定时地发送一些短信、邮件之类的操作,也可能会定时地检查和监控一些标志、参数等。

创建定时任务

在Spring Boot中编写定时任务是非常简单的事,下面通过实例介绍如何在Spring Boot中创建定时任务,实现每过5秒输出一下当前时间。

  • 在Spring Boot的主类中加入@EnableScheduling注解,启用定时任务的配置

@SpringBootApplication
@EnableScheduling
public class Application {
  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }
}
  • 创建定时任务实现类

@Component
public class ScheduledTasks {
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
    @Scheduled(fixedRate = 5000)
    public void reportCurrentTime() {
        log.info("现在时间:" + dateFormat.format(new Date()));
    }
}
  • 运行程序,控制台中可以看到类似如下输出,定时任务开始正常运作了。

2021-07-13 14:56:56.413  INFO 34836 --- [           main] c.d.chapter71.Chapter71Application       : Started Chapter71Application in 1.457 seconds (JVM running for 1.835)
2021-07-13 14:57:01.411  INFO 34836 --- [   scheduling-1] com.didispace.chapter71.ScheduledTasks   : 现在时间:14:57:01
2021-07-13 14:57:06.412  INFO 34836 --- [   scheduling-1] com.didispace.chapter71.ScheduledTasks   : 现在时间:14:57:06
2021-07-13 14:57:11.413  INFO 34836 --- [   scheduling-1] com.didispace.chapter71.ScheduledTasks   : 现在时间:14:57:11
2021-07-13 14:57:16.413  INFO 34836 --- [   scheduling-1] com.didispace.chapter71.ScheduledTasks   : 现在时间:14:57:16

@Scheduled详解

在上面的入门例子中,使用了@Scheduled(fixedRate = 5000) 注解来定义每过5秒执行的任务。对于@Scheduled的使用,我们从源码里看看有哪些配置:

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {
  String CRON_DISABLED = ScheduledTaskRegistrar.CRON_DISABLED;
  String cron() default "";
  String zone() default "";
  long fixedDelay() default -1;
  String fixedDelayString() default "";
  long fixedRate() default -1;
  String fixedRateString() default "";
  long initialDelay() default -1;
  String initialDelayString() default "";
}

这些具体配置信息的含义如下:

  • cron:通过cron表达式来配置执行规则
  • zone:cron表达式解析时使用的时区
  • fixedDelay:上一次执行结束到下一次执行开始的间隔时间(单位:ms)
  • fixedDelayString:上一次任务执行结束到下一次执行开始的间隔时间,使用java.time.Duration#parse解析
  • fixedRate:以固定间隔执行任务,即上一次任务执行开始到下一次执行开始的间隔时间(单位:ms),若在调度任务执行时,上一次任务还未执行完毕,会加入worker队列,等待上一次执行完成后立即执行下一次任务
  • fixedRateString:与fixedRate逻辑一致,只是使用java.time.Duration#parse解析
  • initialDelay:首次任务执行的延迟时间
  • initialDelayString:首次任务执行的延迟时间,使用java.time.Duration#parse解析

思考与进阶

是不是这样实现定时任务很简单呢?那么继续思考一下这种实现方式是否存在什么弊端呢?

可能初学者不太容易发现问题,但如果你已经有一定的线上项目经验的话,问题也是显而易见的:这种模式实现的定时任务缺少在集群环境下的协调机制。

什么意思呢?假设,我们要实现一个定时任务,用来每天网上统计某个数据然后累加到原始数据上。我们开发测试的时候不会有问题,因为都是单进程在运行的。但是,当我们把这样的定时任务部署到生产环境时,为了更高的可用性,启动多个实例是必须的。此时,时间一到,所有启动的实例就会同时开始执行这个任务。那么问题也就出现了,因为有累加操作,最终我们的结果就会出现问题。

解决这样问题的方式很多种,比较通用的就是采用分布式锁的方式,让同类任务之前的时候以分布式锁的方式来控制执行顺序,比如:使用Redis、Zookeeper等具备分布式锁功能的中间件配合就能很好的帮助我们来协调这类任务在集群模式下的执行规则。

除此之外,那么你还有什么好方法来解决吗?留言说说你的看法吧!不要走开,本系列教《Spring Boot 2.x基础教程》持续更新中哦!。学习过程中如遇困难,建议加入Spring技术交流群,参与交流与讨论,更好的学习与进步!

代码示例

本文的完整工程可以查看下面仓库中的chapter7-1目录:

目录
相关文章
|
1月前
|
Java 调度 Spring
Spring之定时任务基本使用篇
本文介绍了在Spring Boot项目中使用定时任务的基本方法。主要通过`@Scheduled`注解实现,需添加`@EnableScheduling`开启定时任务功能。文中详细解析了Cron表达式的语法及常见实例,如每秒、每天特定时间执行等。此外,还探讨了多个定时任务的执行方式(并行或串行)及其潜在问题,并留待后续深入讨论。
108 64
|
4月前
|
JSON Java Maven
实现Java Spring Boot FCM推送教程
本指南介绍了如何在Spring Boot项目中集成Firebase云消息服务(FCM),包括创建项目、添加依赖、配置服务账户密钥、编写推送服务类以及发送消息等步骤,帮助开发者快速实现推送通知功能。
216 2
|
4月前
|
Java BI 调度
Java Spring的定时任务的配置和使用
遵循上述步骤,你就可以在Spring应用中轻松地配置和使用定时任务,满足各种定时处理需求。
214 1
|
4月前
|
存储 Java API
简单两步,Spring Boot 写死的定时任务也能动态设置:技术干货分享
【10月更文挑战第4天】在Spring Boot开发中,定时任务通常通过@Scheduled注解来实现,这种方式简单直接,但存在一个显著的限制:任务的执行时间或频率在编译时就已经确定,无法在运行时动态调整。然而,在实际工作中,我们往往需要根据业务需求或外部条件的变化来动态调整定时任务的执行计划。本文将分享一个简单两步的解决方案,让你的Spring Boot应用中的定时任务也能动态设置,从而满足更灵活的业务需求。
326 4
|
5月前
|
XML JavaScript Java
Spring Retry 教程
Spring Retry 是 Spring 提供的用于处理方法重试的库,通过 AOP 提供声明式重试机制,不侵入业务逻辑代码。主要步骤包括:添加依赖、启用重试机制、设置重试策略(如异常类型、重试次数、延迟策略等),并可定义重试失败后的回调方法。适用于因瞬时故障导致的操作失败场景。
Spring Retry 教程
|
4月前
|
JSON Java Maven
实现Java Spring Boot FCM推送教程
详细介绍实现Java Spring Boot FCM推送教程
140 0
|
6月前
|
SQL Java 数据库连接
Spring Boot联手MyBatis,打造开发利器:从入门到精通,实战教程带你飞越编程高峰!
【8月更文挑战第29天】Spring Boot与MyBatis分别是Java快速开发和持久层框架的优秀代表。本文通过整合Spring Boot与MyBatis,展示了如何在项目中添加相关依赖、配置数据源及MyBatis,并通过实战示例介绍了实体类、Mapper接口及Controller的创建过程。通过本文,你将学会如何利用这两款工具提高开发效率,实现数据的增删查改等复杂操作,为实际项目开发提供有力支持。
501 0
|
6月前
|
Java 开发者 Spring
Spring Boot实战宝典:揭秘定时任务的幕后英雄,让业务处理如流水般顺畅,轻松驾驭时间管理艺术!
【8月更文挑战第29天】在现代应用开发中,定时任务如数据备份、报告生成等至关重要。Spring Boot作为流行的Java框架,凭借其强大的集成能力和简洁的配置方式,为开发者提供了高效的定时任务解决方案。本文详细介绍了如何在Spring Boot项目中启用定时任务支持、编写定时任务方法,并通过实战案例展示了其在业务场景中的应用,同时提供了注意事项以确保任务的正确执行。
71 0
|
6天前
|
Java 数据库 开发者
详细介绍SpringBoot启动流程及配置类解析原理
通过对 Spring Boot 启动流程及配置类解析原理的深入分析,我们可以看到 Spring Boot 在启动时的灵活性和可扩展性。理解这些机制不仅有助于开发者更好地使用 Spring Boot 进行应用开发,还能够在面对问题时,迅速定位和解决问题。希望本文能为您在 Spring Boot 开发过程中提供有效的指导和帮助。
43 12
|
9天前
|
Java 应用服务中间件 Maven
SpringBoot项目打包成war包
通过上述步骤,我们成功地将一个Spring Boot应用打包成WAR文件,并部署到外部的Tomcat服务器中。这种方式适用于需要与传统Servlet容器集成的场景。
29 8