项目中使用不同的定时任务组件完成定时任务工作,比如定时查询订单,定时请求未收到响应的支付响应等,下面列举了常用的定时任务: spring定时器,Quartz和分布式定时任务XXL-JOB。
项目开发中,经常会遇到定时任务的场景,Spring提供了
@Scheduled注解
,方便进行定时任务的开发。
@EnableScheduling
public class BookApp {
public static void main(String[] args) {
SpringApplication.run(BookApp.class, args);
}
}
注意:业务方法中不能有参数.
@Scheduled(cron = "0 7 22 * * ? ")
@Overridepublic void testSchedule() {
System.out.println("-------- 测试定时器----------");
}
参数 | 含义 | 案例 |
---|---|---|
ron | 任务执行的cron表达式 | 0/1 * * * * ? |
zone | cron表达时解析使用的时区,默认为服务器的本地时区,使用java.util.TimeZone#getTimeZone(String)方法解析 | GMT-8:00 |
fixedDelay | 上一次任务执行结束到下一次执行开始的间隔时间,单位为ms | 1000 |
fixedDelayString | 上一次任务执行结束到下一次执行开始的间隔时间,使用java.time.Duration#parse解析 | PT15M |
fixedRate | 以固定间隔执行任务,即上一次任务执行开始到下一次执行开始的间隔时间,单位为ms,若在调度任务执行时,上一次任务还未执行完毕,会加入worker队列,等待上一次执行完成后立即执行下一次任务 | 2000 |
fixedRateString | 与fixedRate逻辑一致,只是使用java.time.Duration#parse解析 | PT15M |
initialDelay | 首次任务执行的延迟时间 | 1000 |
initialDelayString | 首次任务执行的延迟时间,使用java.time.Duration#parse解析 | PT15M |
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,完全由Java开发,可以用来执行定时任务,类似于java.util.Timer。但是相较于Timer, Quartz增加了很多功能:
- 持久性作业 - 就是保持调度定时的状态;
- 作业管理 - 对调度作业进行有效的管理;
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
定义定时器任务类,实现QuartzJobBean
@Slf4j
public class BookJob extends QuartzJobBean {
@Autowired
private RedisTemplate<String,Object> redisTemplate;
@Autowired
private IBookTypeDao bookTypeDao;
@Autowired
private IPublisherDao publisherDao;
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
bookTypeDao.selectList(null).forEach(bt->
redisTemplate.opsForValue().set("bt:"+bt.getId(), bt));
log.debug("{},加载图书类型成功....",new Date());
publisherDao.selectList(null).forEach(publisher ->
redisTemplate.opsForValue().set("p:"+ publisher.getId(), publisher));
log.debug("{},加载出版社成功....",new Date());
}
}
@Configuration
public class JobConfig {
@Bean
public JobDetail jobDetail(){
return JobBuilder.newJob(BookJob.class)
.storeDurably(true)
.build();
}
@Bean
public Trigger trigger(){
return TriggerBuilder.newTrigger()
.forJob(jobDetail())
.withSchedule(CronScheduleBuilder.cronSchedule("0 36 22 * * ?"))
.build();
}
}
[root@localhost ~]# docker pull xuxueli/xxl-job-admin:2.3.1
2.3.1: Pulling from xuxueli/xxl-job-admin
214ca5fb9032: Pull complete
ebf31789c5c1: Pull complete
ab322dde1f12: Pull complete
bff82a7b3b2f: Pull complete
ea84816897f1: Pull complete
915f8f5ae0d3: Pull complete
Digest: sha256:8da4a9dda4b1438c173ca6e0726ade3459da85b5dc36c7ffac63062bd0c11e1d
Status: Downloaded newer image for xuxueli/xxl-job-admin:2.3.1
docker.io/xuxueli/xxl-job-admin:2.3.1
在文档中执行tables_xxl_job.sql(xxl-job-master\doc\db)
·
创建日志的文件夹 /usr/local/software/xxl-job/logs
docker run -it \
--name xxl-job-admin \
-p 9898:8080 \
-e PARAMS="--spring.datasource.url=jdbc:mysql://192.168.198.128:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai --spring.datasource.username=root --spring.datasource.password=123" \
-v /usr/local/software/xxl-job/logs:/data/applogs \
-d xuxueli/xxl-job-admin:2.3.1
执行结果
[root@localhost xxl-job]# docker run -it \
> --name xxl-job-admin \
> -p 9898:8080 \
> -e PARAMS="--spring.datasource.url=jdbc:mysql://192.168.198.128:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai --spring.datasource.username=root --spring.datasource.password=123" \
> -v /usr/local/software/xxl-job/logs:/data/applogs \
> -d xuxueli/xxl-job-admin:2.3.1
1fc4454f66209ea10d3bf0dc74083594be00715107debd726f1ad903470c5a7a
docker-compose版本
version: '2'
networks:
wn_docker_net:
external: true
services:
xxl-job:
build: .
image: xuxueli/xxl-job-admin:2.3.1
container_name: xxl-job
ports:
- "9898:8080"
environment:
PARAMS: '--spring.datasource.url=jdbc:mysql://192.168.198.128:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
--spring.datasource.username=root
--spring.datasource.password=123'
volumes:
- /usr/local/software/xxl-job/logs:/data/applog
networks:
wn_docker_net:
#在自定义网络中指定IP
ipv4_address: 172.18.12.100
docker-compose up -d
http://192.168.198.128:9898/xxl-job-admin
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>2.3.1</version>
</dependency>
也可以写在本地,application.yml
package com.wnhz.wnmap.common.config;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@Slf4j
public class XxlJobConfig {
@Value("${xxl.job.admin.addresses}")
private String adminAddresses;
@Value("${xxl.job.executor.appname}")
private String appname;
@Value("${xxl.job.executor.port}")
private int port;
@Value("${xxl.job.accessToken}")
private String token;
@Bean
public XxlJobSpringExecutor xxlJobExecutor() {
log.info(">>>>>>>>>>> xxl-job 配置开始初始化 init........");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppname(appname);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(token);
return xxlJobSpringExecutor;
}
}
package com.wnhz.wnmap.smovie.genre.job;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class GenreJob {
@XxlJob("firstTryHandler")
public void execute() {
// 获取参数
String param = XxlJobHelper.getJobParam();
//控制台输出日志
log.info("firstTryHandler 任务开始执行>>>> execute...");
//写日志到调度中心日志中
XxlJobHelper.log("myXxlJobHandler execute...");
// 设置任务结果
XxlJobHelper.handleSuccess();
}
}
不需要修改,查询为主
查询调度日志
)]
不需要修改,查询为主
[外链图片转存中…(img-TWECjiA7-1703407550628)]
查询调度日志
[外链图片转存中…(img-FTv5lnEz-1703407550629)]
[外链图片转存中…(img-NP2gXAlf-1703407550629)]
[外链图片转存中…(img-6fBWqbDA-1703407550630)]
[外链图片转存中…(img-b2Cjujyl-1703407550630)]
[外链图片转存中…(img-dMUJt30J-1703407550631)]