项目中常用的定时任务

发布时间:2023年12月27日

定时任务

项目中使用不同的定时任务组件完成定时任务工作,比如定时查询订单,定时请求未收到响应的支付响应等,下面列举了常用的定时任务: spring定时器,Quartz和分布式定时任务XXL-JOB。

Spring定时器@Scheduled

项目开发中,经常会遇到定时任务的场景,Spring提供了@Scheduled注解,方便进行定时任务的开发。

开发流程

启动类添加@EnableSchedul
@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("-------- 测试定时器----------");
}
@scheduled常用参数
参数含义案例
ron任务执行的cron表达式0/1 * * * * ?
zonecron表达时解析使用的时区,默认为服务器的本地时区,使用java.util.TimeZone#getTimeZone(String)方法解析GMT-8:00
fixedDelay上一次任务执行结束到下一次执行开始的间隔时间,单位为ms1000
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

image-20231020141558836

Quartz

Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,完全由Java开发,可以用来执行定时任务,类似于java.util.Timer。但是相较于Timer, Quartz增加了很多功能:

  • 持久性作业 - 就是保持调度定时的状态;
  • 作业管理 - 对调度作业进行有效的管理;

开发流程

引入依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
定义QuartzJobBean

定义定时器任务类,实现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();
    }
}

XXL-JOB

XXL-JOB v2.3.1,分布式任务调度平台

安装XXL-JOB

下载docker版
[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

创建xxl_job库

在文档中执行tables_xxl_job.sql(xxl-job-master\doc\db)

image-20230826110857700

image-20230826110930112

image-20230826111007318

image-20231203185250718

image-20230826110655028·

创建日志挂载

创建日志的文件夹 /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

image-20230826111122931

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

image-20231203192555166

image-20230826113257145

springboot整合XXL-JOB

引入依赖
<dependency>
    <groupId>com.xuxueli</groupId>
    <artifactId>xxl-job-core</artifactId>
    <version>2.3.1</version>
</dependency>
创建配置类
将配置信息写入nacos

也可以写在本地,application.yml

image-20230826183540803

创建xxl-job的配置类
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();
    }
}

管理端配置xxl-job

创建任务

image-20230826184018409

image-20230826184149059

image-20230826184248781

image-20230826184344033

image-20231203200556545

执行器管理

不需要修改,查询为主

image-20230826184453122

调度日志

查询调度日志

image-20230826184550859

运行程序

image-20230826184647096

image-20230826184742966

image-20230826184940908

image-20230826184821523

)]

执行器管理

不需要修改,查询为主

[外链图片转存中…(img-TWECjiA7-1703407550628)]

调度日志

查询调度日志

[外链图片转存中…(img-FTv5lnEz-1703407550629)]

运行程序

[外链图片转存中…(img-NP2gXAlf-1703407550629)]

[外链图片转存中…(img-6fBWqbDA-1703407550630)]

[外链图片转存中…(img-b2Cjujyl-1703407550630)]

[外链图片转存中…(img-dMUJt30J-1703407550631)]

文章来源:https://blog.csdn.net/qq_36115196/article/details/135183549
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。