在目前的SpringBoot
项目中想要使用定时任务十分简单,只需要在方法上添加@Scheduled
注解即可
如下进行使用,首先要在启动类上加上@EnableScheduling
注解
package com.banmoon;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@EnableScheduling
@SpringBootApplication
public class WebBaseMain {
public static void main(String[] args) {
SpringApplication.run(WebBaseMain.class, args);
}
}
再其次,就等在bean
的方法上加上@Scheduled
注解,填上cron
表达式或者其他属性,即刻完成
package com.banmoon.task;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
/**
* @author banmoon
* @date 2024/07/23 20:06:05
*/
@Slf4j
@Component
public class SpringScheduledTask {
@Scheduled(cron = "0/5 * * * * ?")
public void simpleTask() throws InterruptedException {
log.info("测试");
TimeUnit.SECONDS.sleep(2);
}
}
启动项目,查看控制台
讲讲@Scheduled
表达式的属性
long
,一个是String
timeUnit
修改单位timeUnit
修改单位timeUnit
修改单位java.util.concurrent.TimeUnit
来修改
fixedDelay
和fixedRate
有什么不同fixedDelay
:代表了上一个任务结束,与下一个任务开始的时间间隔fixedRate
:代表了上一个任务开始,与下一个任务开始的时间间隔 通俗来讲,假设他们都设置了5
秒钟fixedDelay
:当前任务执行完后,总会等待5
秒钟再执行下一个fixedRate
:当前任务开始执行,5
秒钟过去了,下个任务直接开始运行,不管这个当前任务有没有跑完
讲讲这种定时任务的弊端,大家都知道,目前的项目大多都是分布式的
要是像上面这样启动多台机器,他们之间就会相互竞争,每一个服务实例都会执行一遍
对此问题,我们就必须额外引入一个分布式锁,大部分公司应该都会引入redis
作为分布式锁,成本低廉且可控
虽然可以使用
redis
分布式锁,但服务实例之间总会有毫秒之间的间隔差距,尤其是两边机器时间不对正的情况下 往往会出现,一台机器成功加锁、运行完成、释放锁,等这三步完成后 另一台机器慢悠悠的开始,然后重新的开始成功加锁、运行完成、释放锁 可以看到,这就出现了重复。虽然概率很低,但的确可能会出现这种情况
对于上面spring
的定时任务,不适合作为分布式系统的定时任务,故此才有了分布式定时任务
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。