使用quartz实现动态定时任务并且记录任务调度日志

目录

quartz概述

springboot使用quartz

导入依赖

数据库脚本

配置类:QuartzConfig

定时任务job工厂:JobFactory

监听类:ScheduleJobInitListener

抽象类:AbstractQuartzJob

具体实现类:QuartzJobExecution

工具类:JobInvokeUtils

工具类:BeansUtils

定时任务管理类:QuartzManager

定时任务service实现类

定时任务service

测试类

执行结果


quartz概述

Quartz 是 OpenSymphony 开源组织在任务调度领域的一个开源项目,完全基于 Java 实现。该项目于 2009 年被 Terracotta 收购,目前是 Terracotta 旗下的一个项目。读者可以到 http://www.quartz-scheduler.org/站点下载 Quartz 的发布版本及其源代码。

springboot使用quartz

导入依赖

maven

<dependency>
   <groupId>org.quartz-scheduler</groupId>
   <artifactId>quartz</artifactId>
   <version>2.2.1</version>
</dependency>
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context-support</artifactId>
</dependency>

gradle

compile "org.quartz-scheduler:quartz:2.2.1"
compile "org.springframework:spring-context-support"

数据库脚本

DROP TABLE IF EXISTS `task`;
CREATE TABLE `flight_task`  (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
  `job_group` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '任务分组',
  `job_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '任务名称',
  `remaks` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '任务描述',
  `cron` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '任务表达式',
  `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态 0.正常 1.暂停',
  `bean_class` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '任务执行时调用哪个类的方法 包名+类名+方法名',
  `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否已删除',
  `created_by` bigint NULL DEFAULT 1 COMMENT '创建者',
  `created_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
  `updated_by` bigint NULL DEFAULT 1 COMMENT '修改者',
  `updated_time` datetime(0) NULL DEFAULT NULL COMMENT '修改时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '定时任务信息表' ROW_FORMAT = Dynamic;

DROP TABLE IF EXISTS `task_log`;
CREATE TABLE `flight_task_log`  (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
  `job_id` bigint NULL DEFAULT NULL COMMENT '任务id',
  `job_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '名称名称',
  `job_group` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '任务分组',
  `bean_class` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '调用目标字符串',
  `message` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '日志信息',
  `status` tinyint NULL DEFAULT 0 COMMENT '执行状态 0-正常  1-失败',
  `exception_info` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '异常信息',
  `start_time` datetime(0) NULL DEFAULT NULL COMMENT '开始时间',
  `end_time` datetime(0) NULL DEFAULT NULL COMMENT '结束时间',
  `is_deleted` tinyint(1) NULL DEFAULT 0 COMMENT '是否已删除',
  `created_by` bigint NULL DEFAULT 1 COMMENT '创建者',
  `created_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
  `updated_by` bigint NULL DEFAULT 1 COMMENT '修改者',
  `updated_time` datetime(0) NULL DEFAULT NULL COMMENT '修改时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 581 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '定时任务日志表' ROW_FORMAT = Dynamic;

配置类:QuartzConfig

package com.springboot.demo.config;

import org.quartz.Scheduler;
import org.quartz.spi.JobFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import java.io.IOException;
import java.util.Properties;

/**
 * Copyright: Copyright (c) 2021
 *
 * <p> Description:
 *
 * @version 1.0.0 2021/9/3 18:01
 * @since 1.0.0
 */
@Configuration
public class QuartzConfig {

    private static final Logger logger = LoggerFactory.getLogger(QuartzConfig.class);

    private JobFactory jobFactory;

    public QuartzConfig(com.springboot.demo.config.JobFactory jobFactory) {
        this.jobFactory = jobFactory;
    }

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean() {
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        try {
            factory.setSchedulerName("Scheduler");
            factory.setQuartzProperties(quartzProperties());
            // 延时启动
            factory.setStartupDelay(1);
            factory.setApplicationContextSchedulerContextKey("applicationContextKey");
            // 可选,QuartzScheduler
            // 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
            factory.setOverwriteExistingJobs(true);
            factory.setJobFactory(jobFactory);
            // 设置自动启动,默认为true
            factory.setAutoStartup(true);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return factory;
    }

    @Bean
    public Properties quartzProperties() throws IOException {
        // quartz参数
        Properties prop = new Properties();
        // 线程池配置
        prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
        prop.put("org.quartz.threadPool.threadCount", "20");
        prop.put("org.quartz.threadPool.threadPriority", "5");
        return prop;
    }

    @Bean(name = "scheduler")
    public Scheduler scheduler() {
        return schedulerFactoryBean().getScheduler();
    }

}

定时任务job工厂:JobFactory

package com.springboot.demo.config;

import org.quartz.spi.TriggerFiredBundle;

import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.stereotype.Component;

/**
 * Copyright: Copyright (c) 2021
 *
 * <p> Description:
 *
 * @version 1.0.0 2021/9/6 17:47
 * @since 1.0.0
 */
@Component
public class JobFactory extends AdaptableJobFactory {
    /**
     * AutowireCapableBeanFactory接口是BeanFactory的子类
     * 可以连接和填充那些生命周期不被Spring管理的已存在的bean实例
     */
    private AutowireCapableBeanFactory factory;

    public JobFactory(AutowireCapableBeanFactory factory) {
        this.factory = factory;
    }

    /**
     * 创建Job实例
     */
    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        // 实例化对象
        Object job = super.createJobInstance(bundle);
        // 进行注入(Spring管理该Bean)
        factory.autowireBean(job);
        //返回对象
        return job;
    }
}

监听类:ScheduleJobInitListener

package com.springboot.demo.config;

import com.springboot.demo.service.TaskService;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * Copyright: Copyright (c) 2021
 *
 * <p> Description:
 *
 * @version 1.0.0 2021/9/6 11:36
 * @since 1.0.0
 */
@Component
@Order(value = 1)
public class ScheduleJobInitListener implements CommandLineRunner {

    @Resource
    private TaskService taskService;

    @Override
    public void run(String... args) throws Exception {
        try {
            taskService.initSchedule();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

抽象类:AbstractQuartzJob

package com.springboot.demo.utils;

import java.util.Date;

import com.springboot.demo.entity.Task;
import com.springboot.demo.entity.TaskLog;
import com.springboot.demo.service.TaskLogService;
import com.springboot.demo.task.TaskConstants;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Copyright: Copyright (c) 2021
 *
 * <p> Description:
 *
 * @version 1.0.0 2021/9/7 11:29
 * @since 1.0.0
 */
public abstract class AbstractQuartzJob implements Job {

    private static final Logger log = LoggerFactory.getLogger(AbstractQuartzJob.class);

    /**
     * 线程本地变量
     */
    private static ThreadLocal<Date> threadLocal = new ThreadLocal<>();

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        Task task = (Task)context.getMergedJobDataMap().get(TaskConstants.TASK_PROPERTIES);
        try {
            before(context, task);
            doExecute(context, task);
            after(context, task, null);
        } catch (Exception ex) {
            log.error("定时任务执行异常:{}", ex.getMessage());
            after(context, task, ex);
        }
    }

    /**
     * 执行前
     *
     * @param context 工作执行上下文对象
     * @param task 任务
     */
    protected void before(JobExecutionContext context, Task task) {
        threadLocal.set(new Date());
    }

    protected void after(JobExecutionContext context, Task task, Exception ex) {
        Date startTime = threadLocal.get();
        threadLocal.remove();

        TaskLog taskLog = new TaskLog();
        taskLog.setJobId(task.getId());
        taskLog.setJobGroup(task.getJobGroup());
        taskLog.setJobName(task.getJobName());
        taskLog.setInvokeTarget(task.getBeanClass());
        taskLog.setStartTime(startTime);
        taskLog.setEndTime(new Date());
        long runMs = taskLog.getEndTime().getTime() - taskLog.getStartTime().getTime();
        taskLog.setMessage(taskLog.getJobName() + " 总共耗时:" + runMs + "毫秒");
        if (null != ex) {
            taskLog.setStatus(1);
            taskLog.setExceptionInfo(ex.getMessage());
        } else {
            taskLog.setStatus(0);
        }
        BeansUtils.getBean(TaskLogService.class).save(taskLog);
    }

    /**
     * 执行方法
     *
     * @param context 工作执行上下文对象
     * @param task 系统计划任务
     * @throws Exception 执行过程中的异常
     */
    protected abstract void  doExecute(JobExecutionContext context, Task task) throws Exception;
}

具体实现类:QuartzJobExecution

package com.springboot.demo.utils;

import com.springboot.demo.entity.Task;
import org.quartz.JobExecutionContext;

/**
 * Copyright: Copyright (c) 2021
 *
 * <p> Description:
 *
 * @version 1.0.0 2021/9/7 18:37
 * @since 1.0.0
 */
public class QuartzJobExecution extends AbstractQuartzJob {

    @Override
    protected void doExecute(JobExecutionContext context, Task task) throws Exception {
        JobInvokeUtils.invokeMethod(task);
    }
}

工具类:JobInvokeUtils

package com.springboot.demo.utils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import com.springboot.demo.entity.Task;

/**
 * Copyright: Copyright (c) 2021
 *
 * <p> Description:
 *
 * @version 1.0.0 2021/9/7 18:03
 * @since 1.0.0
 */
public class JobInvokeUtils {

    public static void invokeMethod(Task task) throws Exception {
        String beanClass = task.getBeanClass();
        if (beanClass != null && beanClass.length() != 0) {
            String beanName = BeansUtils.getBeanName(beanClass);
            String methodName = BeansUtils.getMethodName(beanClass);
            Object bean = Class.forName(beanName).newInstance();
            invokeMethod(bean, methodName);
        }
    }

    public static void invokeMethod(Object bean, String methodName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Method method = bean.getClass().getDeclaredMethod(methodName);
        method.invoke(bean);
    }

}

工具类:BeansUtils

package com.springboot.demo.utils;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;

/**
 * Copyright: Copyright (c) 2021
 *
 * <p> Description:
 *
 * @version 1.0.0 2021/9/8 11:22
 * @since 1.0.0
 */
@Component
public final class BeansUtils implements BeanFactoryPostProcessor {

    private static ConfigurableListableBeanFactory beanFactory;


    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        BeansUtils.beanFactory = beanFactory;
    }

    public static <T> T getBean(Class<T> cla) throws BeansException {
        return beanFactory.getBean(cla);
    }

    /**
     * 获取bean名称.
     *
     * @param beanClass 目标字符串
     * @return bean名称
     */
    public static String getBeanName(String beanClass) {
        int index = beanClass.lastIndexOf(".");
        return index == -1 ? beanClass : beanClass.substring(0, index);
    }

    /**
     * 获取bean方法.
     *
     * @param beanClass 目标字符串
     * @return method方法
     */
    public static String getMethodName(String beanClass) {
        int endIndex = beanClass.indexOf("(");
        int startIndex = beanClass.lastIndexOf(".");
        if (startIndex == -1) {
            return null;
        }
        return beanClass.substring(startIndex + 1, endIndex);
    }
}

定时任务管理类:QuartzManager

package com.springboot.demo.manager;

import com.springboot.demo.entity.Task;
import com.springboot.demo.task.TaskConstants;
import com.springboot.demo.utils.QuartzJobExecution;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.DateBuilder;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

/**
 * Copyright: Copyright (c) 2021
 *
 * <p> Description:
 *
 * @version 1.0.0 2021/9/6 11:49
 * @since 1.0.0
 */
@Service
public class QuartzManager {

    @Resource
    private Scheduler scheduler;

    /**
     * 得到quartz任务类
     *
     * @param task 执行计划
     * @return 具体执行任务类
     */
    private static Class<? extends Job> getQuartzJobClass(Task task) {
        return QuartzJobExecution.class;
    }

    /**
     * 添加任务job
     *
     * @param task :任务实体类
     * @version 1.0.0 2021/9/6 12:10
     * @since 1.0.0
     */
    @SuppressWarnings("unchecked")
    public void addJob(Task task) {
        try {
            // 创建jobDetail实例, 绑定Job实现类
            // 指明job的名称,所在组的名称,以及绑定Job类
            Class<? extends Job> jobClass = getQuartzJobClass(task);
//            Class<? extends Job> jobClass = (Class<? extends Job>) (Class.forName(task.getBeanClass())).newInstance().getClass();
            // 配置任务名称和组构成任务key
            JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(getJobKey(task.getId(), task.getJobGroup())).build();
            // 定义调度规则
            // 使用cornTrigger规则
            Trigger trigger = TriggerBuilder.newTrigger().withIdentity(task.getJobName(), task.getJobGroup())
                    .startAt(DateBuilder.futureDate(1, DateBuilder.IntervalUnit.SECOND))
                    .withSchedule(CronScheduleBuilder.cronSchedule(task.getCron())).startNow().build();
            jobDetail.getJobDataMap().put(TaskConstants.TASK_PROPERTIES, task);
            // 判断是否存在
            if (scheduler.checkExists(getJobKey(task.getId(), task.getJobGroup()))) {
                // 防止创建时存在数据问题 先移除,然后在执行创建操作
                scheduler.deleteJob(getJobKey(task.getId(), task.getJobGroup()));
            }
            // 把job和触发器注册到任务调度中
            scheduler.scheduleJob(jobDetail, trigger);
            if (task.getStatus() == 1) {
                pauseJob(task);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 构建任务键对象
     */
    public static JobKey getJobKey(Long jobId, String jobGroup) {
        return JobKey.jobKey(TaskConstants.TASK_CLASS_NAME + jobId, jobGroup);
    }

    /**
     * 暂停一个job
     *
     * @param task :任务实体类
     * @version 1.0.0 2021/9/6 12:10
     * @since 1.0.0
     */
    public void pauseJob(Task task) throws SchedulerException {
        scheduler.pauseJob(getJobKey(task.getId(), task.getJobGroup()));
    }

    /**
     * 恢复一个job
     *
     * @param task :任务实体类
     * @version 1.0.0 2021/9/6 12:10
     * @since 1.0.0
     */
    public void resumeJob(Task task) throws SchedulerException {
        scheduler.resumeJob(getJobKey(task.getId(), task.getJobGroup()));
    }

    /**
     * 删除一个job
     *
     * @param task :任务实体类
     * @version 1.0.0 2021/9/6 12:10
     * @since 1.0.0
     */
    public void deleteJob(Task task) throws SchedulerException {
        scheduler.deleteJob(getJobKey(task.getId(), task.getJobGroup()));
    }

    /**
     * 立即触发job
     *
     * @param task :任务实体类
     * @version 1.0.0 2021/9/6 12:10
     * @since 1.0.0
     */
    public void runJobNow(Task task) throws SchedulerException {
        JobDataMap dataMap = new JobDataMap();
        dataMap.put(TaskConstants.TASK_PROPERTIES, task);
        scheduler.triggerJob(getJobKey(task.getId(), task.getJobGroup()), dataMap);
    }

    /**
     * 更新job表达式
     *
     * @param task :任务实体类
     * @version 1.0.0 2021/9/6 12:10
     * @since 1.0.0
     */
    public void updateJobCron(Task task) throws SchedulerException {
        TriggerKey triggerKey = TriggerKey.triggerKey(task.getJobName(), task.getJobGroup());
        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(task.getCron());
        trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
        scheduler.rescheduleJob(triggerKey, trigger);
    }
}

定时任务service实现类

package com.springboot.demo.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.springboot.demo.manager.QuartzManager;
import com.springboot.demo.entity.Task;
import com.springboot.demo.mapper.TaskMapper;
import com.springboot.demo.service.TaskService;

import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.quartz.SchedulerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;

import java.util.List;


/**
 * (Task)表服务实现类
 *
 * @since 2021-09-03 17:55:57
 */
@Service
public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements TaskService {

    private final static Logger logger = LoggerFactory.getLogger(TaskServiceImpl.class);

    @Resource
    private TaskMapper taskMapper;
    @Resource
    private QuartzManager quartzManager;

    @Override
    public IPage<Task> getListByPage(Page<Task> page, Task query) {
        return taskMapper.getListByPage(page, query);
    }

    @Override
    public void initSchedule() {
        List<Task> list = this.list();
        for (Task task : list) {
            quartzManager.addJob(task);
        }
    }

    @Override
    public Boolean updateTaskById(Task task) {
        Task oldTask = this.getById(task.getId());
        if (this.updateById(task)) {
            try {
                quartzManager.deleteJob(oldTask);
                quartzManager.addJob(task);
                return true;
            } catch (SchedulerException e) {
                logger.error("更新job任务表达式异常:{}", e.getMessage());
                return false;
            }
        }
        return false;
    }

    @Override
    public Boolean deleteById(Long id) {
        Task task = this.getById(id);
        if (task.getStatus() == 0) {
            try {
                quartzManager.deleteJob(task);
            } catch (SchedulerException e) {
                logger.error("删除任务异常:{}", e.getMessage());
                return false;
            }
        }
        return this.removeById(id);
    }

    @Override
    public Boolean performOneById(Long id) {
        Task task = this.getById(id);
        try {
            quartzManager.runJobNow(task);
            return true;
        } catch (SchedulerException e) {
            logger.error("立即执行任务异常:{}", e.getMessage());
            return false;
        }
    }

    @Override
    public Boolean performOrSuspendOneById(Long id, Integer status) {
        Task task = this.getById(id);
        task.setStatus(status);
        try {
            if (status == 1) {
                quartzManager.pauseJob(task);
            }
            if (status == 0) {
                quartzManager.resumeJob(task);
            }
        } catch (SchedulerException ex) {
            logger.error("修改任务状态异常:{}", ex.getMessage());
            return false;
        }
        return this.updateById(task);
    }

    @Override
    public Boolean saveTask(Task task) {
        if (this.save(task)) {
            quartzManager.addJob(task);
            return true;
        }
        return false;
    }
}

定时任务service

package com.springboot.demo.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.springboot.demo.entity.Task;

/**
 * (Task)表服务接口
 *
 * @since 2021-09-03 17:55:56
 */
public interface TaskService extends IService<Task> {

    /**
     * 分页查询.
     *
     * @param page  :
     * @param query :
     * @return com.baomidou.mybatisplus.core.metadata.IPage<com.springboot.demo.entity.Task>
     * @since 1.0.0
     */
    IPage<Task> getListByPage(Page<Task> page, Task query);

    /**
     * 初始化加载任务.
     *
     * @since 1.0.0
     */
    void initSchedule();

    /**
     * 修改一个任务.
     *
     * @param task :任务信息
     * @return boolean
     * @since 1.0.0
     */
    Boolean updateTaskById(Task task);

    /**
     * 根据id删除一个任务.
     *
     * @param id :
     * @return boolean
     * @since 1.0.0
     */
    Boolean deleteById(Long id);

    /**
     * 根据id执行一次任务.
     *
     * @param id :id
     * @return boolean
     * @since 1.0.0
     */
    Boolean performOneById(Long id);

    /**
     * 根据id和状态判断执行或暂停一个任务.
     *
     * @param id     : id
     * @param status :状态 0为执行  1为暂停
     * @return boolean
     * @since 1.0.0
     */
    Boolean performOrSuspendOneById(Long id, Integer status);

    /**
     * 保存定时任务.
     * @param task :
     * @return java.lang.Boolean
     * @since 1.0.0
     */
    Boolean saveTask(Task task);
}

测试类

package com.springboot.demo.test;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.stereotype.Component;

/**
 * Copyright: Copyright (c) 2021
 *
 * <p> Description:
 *
 * @version 1.0.0 2021/9/6 18:22
 * @since 1.0.0
 */
@Component("test")
public class Test {

    private static final Logger logger = LoggerFactory.getLogger(Test.class);

    public void test() throws JobExecutionException {
        logger.info("定时任务test():" + new Date());
    }

    public void testOne() throws JobExecutionException {
        logger.info("定时任务testOne():" + new Date());
    }

}

执行结果

结束语

本博客只适用于研究学习为目的,大多为学习笔记,如有错误欢迎指正,如有误导敬请谅解。

  • 9
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用多台负载均衡服务器来进行quartz定时任务的部署和管理时,我们可以采用以下的一些方案和策略。 首先,为了实现负载均衡,我们可以使用负载均衡器(Load Balancer)来将请求均匀地分发到多台quartz定时任务服务器上。负载均衡器可以根据不同的算法,如轮询、最少连接、源IP等,将任务请求分发到相应的服务器,实现资源的平衡利用。 其次,为了保证任务的高可用性和容错性,我们可以将quartz定时任务服务器设置为多节点集群(Cluster)。各个节点之间通过集群管理协议来协调任务的调度和执行,实现任务的弹性扩展和容灾备份。当某个节点出现故障时,其他节点可以接管故障节点的任务,确保任务的持续执行。 另外,为了确保数据的一致性和可靠性,我们可以采用分布式数据库来存储和管理quartz定时任务的相关数据。通过将任务数据分布在多个数据库实例上,并采用数据同步和故障恢复策略,可以避免单点故障和数据丢失的风险。 此外,为了方便任务的监控和管理,我们可以借助一些监控工具和平台来对多台负载均衡服务器上的quartz定时任务进行实时监控和性能分析。通过查看任务的执行情况、日志输出和运行指标,可以及时发现并解决任务执行异常和性能瓶颈问题。 最后,为了提升任务的执行效率和响应速度,我们可以采用异步执行和任务分片的方式来并行执行quartz定时任务。通过将任务拆分成多个子任务,并由多个执行器同时执行,可以减少任务的等待时间和执行时间,提高任务的整体处理能力。 综上所述,通过使用负载均衡器、集群管理、分布式数据库、监控工具和异步执行等技术手段,我们可以实现quartz定时任务在多台负载均衡服务器上的高效部署和管理。这将为我们提供一个稳定、可靠和高性能的定时任务管理平台。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值