定时删除多余的图片
Quartz(石英)
Quartz 核心概念
我们需要明白 Quartz 的几个核心概念,这样理解起 Quartz 的原理就会变得简单了。
Job
表示一个工作,要执行的具体内容。此接口中只有一个方法,如下:
void execute(JobExecutionContext context)
JobDetail 表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。
Trigger 代表一个调度参数的配置,什么时候去调。
Scheduler 代表一个调度容器,一个调度容器中可以注册多个 JobDetail 和 Trigger。当 Trigger 与 JobDetail 组合,就可以被 Scheduler 容器调度了。
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,完全由Java开发,可以用来执行定时任务,类似于java.util.Timer。但是相较于Timer, Quartz增加了很多功能:
持久性作业 - 就是保持调度定时的状态;
作业管理 - 对调度作业进行有效的管理;
大部分公司都会用到定时任务这个功能。
拿火车票购票来说,当你下单后,后台就会插入一条待支付的task(job),一般是30分钟,超过30min后就会执行这个job,去判断你是否支付,未支付就会取消此次订单;当你支付完成之后,后台拿到支付回调后就会再插入一条待消费的task(job),Job触发日期为火车票上的出发日期,超过这个时间就会执行这个job,判断是否使用等。
在我们实际的项目中,当Job过多的时候,肯定不能人工去操作,这时候就需要一个任务调度框架,帮我们自动去执行这些程序。那么该如何实现这个功能呢?
首先我们需要定义实现一个定时功能的接口,我们可以称之为Task(或Job),如定时发送邮件的task(Job),重启机器的task(Job),优惠券到期发送短信提醒的task(Job),实现接口如下:
有了任务之后,还需要一个能够实现触发任务去执行的触发器,触发器Trigger最基本的功能是指定Job的执行时间,执行间隔,运行次数等。
有了Job和Trigger后,怎么样将两者结合起来呢?即怎样指定Trigger去执行指定的Job呢?这时需要一个Schedule,来负责这个功能的实现
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
public class CustomJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println(System.currentTimeMillis());
try {
Object name1 = jobExecutionContext.getScheduler().getContext().get("name1");
System.out.println(name1);
}catch (Exception e){
e.printStackTrace();
}
Object name2 = jobExecutionContext.getJobDetail().getJobDataMap().get("name2");
System.out.println(name2);
Object name3 = jobExecutionContext.getTrigger().getJobDataMap().get("name3");
System.out.println(name3);
System.out.println("============");
}
}
public static void main(String[]args)throws Exception{
//容器
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.getContext().put("name1","scheduler中放数据");
//调度
JobDetail jobDetail = JobBuilder.newJob(CustomJob.class)
.withIdentity("myjob", "mygroup")
.build();
jobDetail.getJobDataMap().put("name2","jobdetail中放数据");
long l = System.currentTimeMillis() + 5000;
//触发
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
//.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(3).repeatForever())
//.startAt(new Date(l))
.withSchedule(CronScheduleBuilder.cronSchedule("0/3 * * * * ? "))
.build();
trigger.getJobDataMap().put("name3","trigger中放数据");
//结合
scheduler.scheduleJob(jobDetail,trigger);
//执行
scheduler.start();
}
任务调度框架
容器、调度、触发
都可以传递数据
Simple Trigger
CronTrigger 更加灵活
cron 谷物 linux 中调度控制
Cron-Expressions用于配置CronTrigger的实例。Cron Expressions是由七个子表达式组成的字符串,用于描述日程表的各个细节。这些子表达式用空格分隔,并表示:
在线生成器地址:
https://www.bejson.com/othertools/cron/
job 模块 定时清理文件
三个依赖 不用加 quartz 依赖 springboot 封装了
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.4.9</version>
</dependency>
<dependency>
<groupId>com.offcn</groupId>
<artifactId>offcnpe_util</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
Spring 家族的 Task 和 Quartz 都是任务调度框架
exclude 没有数据源
注解 EnableScheduling
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableScheduling
public class JobApplication {
public static void main(String[] args) {
SpringApplication.run(JobApplication.class,args);
}
}
任务任意方法 不用实现
任务 -- 执行删除多余文件操作
求差 -- 找出多余文件的名称
到指定文件路径按照多余文件名称删除文件
Redis upload、add 缓存也需要更新
注解 Scheduled(cron=表达式)
//任务 -- 执行删除多余文件工作8dfd059e72d64b2f90d3faf473c2b26f.jpg 3fffcf67a16f43feb51bcb93f753145e.jpg
@Component
public class FileDeleteJob{
@Autowired
private StringRedisTemplate redisTemplate;
//@Scheduled(cron = "0 59 23 * * ? ")
@Scheduled(cron = "0/10 * * * * ? ")
public void deleteFile(){
//求差 -- 找出多余文件的名称
Set<String> names = redisTemplate.opsForSet().difference(RedisConstant.UPLOAD_KEY, RedisConstant.ADD_KEY);
//到指定路径按照多余文件的名称删除文件
for(String name : names){
String path = "C:\\Users\\Administrator\\Desktop\\offcnpe";
File file = new File(path,name);
file.delete();
//redis的集合更新
redisTemplate.boundSetOps(RedisConstant.UPLOAD_KEY).remove(name);
}