阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

使用Scheduler

287次阅读
没有评论

共计 3029 个字符,预计需要花费 8 分钟才能阅读完成。

在很多应用程序中,经常需要执行定时任务。例如,每天或每月给用户发送账户汇总报表,定期检查并发送系统状态报告,等等。

定时任务我们在使用线程池一节中已经讲到了,Java 标准库本身就提供了定时执行任务的功能。在 Spring 中,使用定时任务更简单,不需要手写线程池相关代码,只需要两个注解即可。

我们还是以实际代码为例,建立工程 spring-integration-schedule,无需额外的依赖,我们可以直接在AppConfig 中加上 @EnableScheduling 就开启了定时任务的支持:

@Configuration
@ComponentScan
@EnableWebMvc
@EnableScheduling
@EnableTransactionManagement
@PropertySource({"classpath:/jdbc.properties", "classpath:/task.properties"})
public class AppConfig {...}

接下来,我们可以直接在一个 Bean 中编写一个 public void 无参数方法,然后加上 @Scheduled 注解:

@Component
public class TaskService {final Logger logger = LoggerFactory.getLogger(getClass());

    @Scheduled(initialDelay = 60_000, fixedRate = 60_000)
    public void checkSystemStatusEveryMinute() {logger.info("Start check system status...");
    }
}

上述注解指定了启动延迟 60 秒,并以 60 秒的间隔执行任务。现在,我们直接运行应用程序,就可以在控制台看到定时任务打印的日志:

2020-06-03 18:47:32 INFO  [pool-1-thread-1] c.i.learnjava.service.TaskService - Start check system status...
2020-06-03 18:48:32 INFO  [pool-1-thread-1] c.i.learnjava.service.TaskService - Start check system status...
2020-06-03 18:49:32 INFO  [pool-1-thread-1] c.i.learnjava.service.TaskService - Start check system status...

如果没有看到定时任务的日志,需要检查:

  • 是否忘记了在 AppConfig 中标注@EnableScheduling
  • 是否忘记了在定时任务的方法所在的 class 标注@Component

除了可以使用 fixedRate 外,还可以使用fixedDelay,两者的区别我们已经在使用线程池一节中讲过,这里不再重复。

有的童鞋在实际开发中会遇到一个问题,因为 Java 的注解全部是常量,写死了fixedDelay=30000,如果根据实际情况要改成 60 秒怎么办,只能重新编译?

我们可以把定时任务的配置放到配置文件中,例如task.properties

task.checkDiskSpace=30000

这样就可以随时修改配置文件而无需动代码。但是在代码中,我们需要用 fixedDelayString 取代fixedDelay

@Component
public class TaskService {
    ...

    @Scheduled(initialDelay = 30_000, fixedDelayString = "${task.checkDiskSpace:30000}")
    public void checkDiskSpaceEveryMinute() {logger.info("Start check disk space...");
    }
}

注意到上述代码的注解参数 fixedDelayString 是一个属性占位符,并配有默认值 30000,Spring 在处理 @Scheduled 注解时,如果遇到String,会根据占位符自动用配置项替换,这样就可以灵活地修改定时任务的配置。

此外,fixedDelayString还可以使用更易读的Duration,例如:

@Scheduled(initialDelay = 30_000, fixedDelayString = "${task.checkDiskSpace:PT2M30S}")

以字符串 PT2M30S 表示的 Duration 就是 2 分 30 秒,请参考 LocalDateTime 一节的 Duration 相关部分。

多个 @Scheduled 方法完全可以放到一个 Bean 中,这样便于统一管理各类定时任务。

使用 Cron 任务

还有一类定时任务,它不是简单的重复执行,而是按时间触发,我们把这类任务称为 Cron 任务,例如:

  • 每天凌晨 2:15 执行报表任务;
  • 每个工作日 12:00 执行特定任务;
  • ……

Cron 源自 Unix/Linux 系统自带的 crond 守护进程,以一个简洁的表达式定义任务触发时间。在 Spring 中,也可以使用 Cron 表达式来执行 Cron 任务,在 Spring 中,它的格式是:

秒 分 小时 天 月份 星期 年

年是可以忽略的,通常不写。每天凌晨 2:15 执行的 Cron 表达式就是:

0 15 2 * * *

每个工作日 12:00 执行的 Cron 表达式就是:

0 0 12 * * MON-FRI

每个月 1 号,2 号,3 号和 10 号 12:00 执行的 Cron 表达式就是:

0 0 12 1-3,10 * *

在 Spring 中,我们定义一个每天凌晨 2:15 执行的任务:

@Component
public class TaskService {
    ...

    @Scheduled(cron = "${task.report:0 15 2 * * *}")
    public void cronDailyReport() {logger.info("Start daily report task...");
    }
}

Cron 任务同样可以使用属性占位符,这样修改起来更加方便。

Cron 表达式还可以表达每 10 分钟执行,例如:

0 */10 * * * *

这样,在每个小时的 0:00,10:00,20:00,30:00,40:00,50:00 均会执行任务,实际上它可以取代 fixedRate 类型的定时任务。

集成 Quartz

在 Spring 中使用定时任务和 Cron 任务都十分简单,但是要注意到,这些任务的调度都是在每个 JVM 进程中的。如果在本机启动两个进程,或者在多台机器上启动应用,这些进程的定时任务和 Cron 任务都是独立运行的,互不影响。

如果一些定时任务要以集群的方式运行,例如每天 23:00 执行检查任务,只需要集群中的一台运行即可,这个时候,可以考虑使用 Quartz。

Quartz 可以配置一个 JDBC 数据源,以便存储所有的任务调度计划以及任务执行状态。也可以使用内存来调度任务,但这样配置就和使用 Spring 的调度没啥区别了,额外集成 Quartz 的意义就不大。

Quartz 的 JDBC 配置比较复杂,Spring 对其也有一定的支持。要详细了解 Quartz 的集成,请参考 Spring 的文档。

思考:如果不使用 Quartz 的 JDBC 配置,多个 Spring 应用同时运行时,如何保证某个任务只在某一台机器执行?

练习

使用 Scheduler 执行定时任务。

下载练习

小结

Spring 内置定时任务和 Cron 任务的支持,编写调度任务十分方便。

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-08-05发表,共计3029字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19351
评论数
4
阅读量
7984891
文章搜索
热门文章
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...
再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...
飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛 NAS 中安装 Navidrome 音乐文件中文标签乱码问题解决、安装 FntermX 终端 问题背景 ...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
Prometheus:监控系统的部署与指标收集

Prometheus:监控系统的部署与指标收集

Prometheus:监控系统的部署与指标收集 在云原生体系中,Prometheus 已成为最主流的监控与报警...
星哥带你玩飞牛NAS-4:飞牛NAS安装istore旁路由,家庭网络升级的最佳实践

星哥带你玩飞牛NAS-4:飞牛NAS安装istore旁路由,家庭网络升级的最佳实践

星哥带你玩飞牛 NAS-4:飞牛 NAS 安装 istore 旁路由,家庭网络升级的最佳实践 开始 大家好我是...
仅2MB大小!开源硬件监控工具:Win11 无缝适配,CPU、GPU、网速全维度掌控

仅2MB大小!开源硬件监控工具:Win11 无缝适配,CPU、GPU、网速全维度掌控

还在忍受动辄数百兆的“全家桶”监控软件?后台偷占资源、界面杂乱冗余,想查个 CPU 温度都要层层点选? 今天给...
星哥带你玩飞牛NAS-1:安装飞牛NAS

星哥带你玩飞牛NAS-1:安装飞牛NAS

星哥带你玩飞牛 NAS-1:安装飞牛 NAS 前言 在家庭和小型工作室场景中,NAS(Network Atta...
开发者福利:免费 .frii.site 子域名,一分钟申请即用

开发者福利:免费 .frii.site 子域名,一分钟申请即用

  开发者福利:免费 .frii.site 子域名,一分钟申请即用 前言 在学习 Web 开发、部署...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
星哥带你玩飞牛NAS-16:不再错过公众号更新,飞牛NAS搭建RSS

星哥带你玩飞牛NAS-16:不再错过公众号更新,飞牛NAS搭建RSS

  星哥带你玩飞牛 NAS-16:不再错过公众号更新,飞牛 NAS 搭建 RSS 对于经常关注多个微...
多服务器管理神器 Nexterm 横空出世!NAS/Win/Linux 通吃,SSH/VNC/RDP 一站式搞定

多服务器管理神器 Nexterm 横空出世!NAS/Win/Linux 通吃,SSH/VNC/RDP 一站式搞定

多服务器管理神器 Nexterm 横空出世!NAS/Win/Linux 通吃,SSH/VNC/RDP 一站式搞...
颠覆 AI 开发效率!开源工具一站式管控 30+大模型ApiKey,秘钥付费+负载均衡全搞定

颠覆 AI 开发效率!开源工具一站式管控 30+大模型ApiKey,秘钥付费+负载均衡全搞定

  颠覆 AI 开发效率!开源工具一站式管控 30+ 大模型 ApiKey,秘钥付费 + 负载均衡全...
支付宝、淘宝、闲鱼又双叕崩了,Cloudflare也瘫了连监控都挂,根因藏在哪?

支付宝、淘宝、闲鱼又双叕崩了,Cloudflare也瘫了连监控都挂,根因藏在哪?

支付宝、淘宝、闲鱼又双叕崩了,Cloudflare 也瘫了连监控都挂,根因藏在哪? 最近两天的互联网堪称“故障...
国产开源公众号AI知识库 Agent:突破未认证号限制,一键搞定自动回复,重构运营效率

国产开源公众号AI知识库 Agent:突破未认证号限制,一键搞定自动回复,重构运营效率

国产开源公众号 AI 知识库 Agent:突破未认证号限制,一键搞定自动回复,重构运营效率 大家好,我是星哥,...