分布式调度之Quartz

/**
 * @Author: rhb
 * @Date: 2020/9/29 19:22
 * @Description: quartz核心配置类
 */
@Configuration
public class QuartzConfig {

    @Value("${quartz.driverClassName}")
    private String driverClassName;
    @Value("${quartz.url}")
    private String url;
    @Value("${quartz.username}")
    private String username;
    @Value("${quartz.password}")
    private String password;
    @Value("${quartz.maxConnections}")
    private String maxConnections;
    @Value("${quartz.publickey}")
    private String publicKey;

    @Bean
    public Properties quartzProperties() throws Exception {
        password = ConfigTools.decrypt(publicKey, password);

        PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
        Properties prop = new Properties();

        // scheduler配置
        prop.put("org.quartz.scheduler.instanceName", "DouYinQuartzScheduler");         // 调度器的实例名
        prop.put("org.quartz.scheduler.instanceId", "AUTO");                            // 自动生成id
        prop.put("org.quartz.scheduler.skipUpdateCheck", "true");                       // 跳过更新

        // JobStore配置
        prop.put("org.quartz.jobStore.isClustered", "true");                                                 //启用集群
        prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");                                                // 表名前缀
        prop.put("org.quartz.jobStore.dataSource", "quartzDataSource");                                      // 定义datasource名称
        prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");                    // 持久化
        prop.put("org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.StdJDBCDelegate"); // JDBC的驱动程序
        prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS WHERE LOCK_NAME = ? FOR UPDATE");
        prop.put("org.quartz.jobStore.txIsolationLevelSerializable","true");                                 // 防止数据库在高负载下锁定超时以及“持久”事务

        // ThreadPool配置
        prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");   // 线程池的名字
        prop.put("org.quartz.threadPool.threadCount", "5");                             // 指定线程数量
        prop.put("org.quartz.threadPool.threadPriority", "5");                          // 线程优先级(1-10)默认为5
        prop.put("org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread", "true");

        // mysql数据源配置
        prop.put("org.quartz.dataSource.quartzDataSource.driver", driverClassName);
        prop.put("org.quartz.dataSource.quartzDataSource.URL", url);
        prop.put("org.quartz.dataSource.quartzDataSource.user", username);
        prop.put("org.quartz.dataSource.quartzDataSource.password", password);
        prop.put("org.quartz.dataSource.quartzDataSource.maxConnections", maxConnections);
        prop.put("org.quartz.dataSource.quartzDataSource.provider","hikaricp");
        prop.put("org.quartz.dataSource.quartzDataSource.maximumPoolSize","10");
        prop.put("org.quartz.dataSource.quartzDataSource.connectionTestQuery","SELECT 1");
        prop.put("org.quartz.dataSource.quartzDataSource.validationTimeout","5000");
        prop.put("org.quartz.dataSource.quartzDataSource.idleTimeout","0");

        //在quartz.properties中的属性被读取并注入后再初始化对象
        propertiesFactoryBean.setProperties(prop);
        propertiesFactoryBean.afterPropertiesSet();
        return propertiesFactoryBean.getObject();
    }

    @Bean
    public JobFactory jobFactory(ApplicationContext applicationContext){
        AutowiredSpringBeanJobFactory jobFactory = new AutowiredSpringBeanJobFactory();
        jobFactory.setApplicationContext(applicationContext);
        return jobFactory;
    }

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory){
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        //可选,QuartzScheduler启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录
        schedulerFactoryBean.setOverwriteExistingJobs(true);
        //设置自动启动
        schedulerFactoryBean.setAutoStartup(true);
        schedulerFactoryBean.setJobFactory(jobFactory);
        try {
            schedulerFactoryBean.setQuartzProperties(quartzProperties());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return schedulerFactoryBean;
    }

    /**
     * 初始注入scheduler
    */
    @Bean(name = "Scheduler")
    public Scheduler scheduler(SchedulerFactoryBean schedulerFactoryBean) throws SchedulerException {
        return schedulerFactoryBean.getScheduler();
    }

    /**
     * quartz初始化监听器 : 这个监听器可以监听到工程的启动,在工程停止再启动时可以让已有的定时任务继续进行。
     */
    @Bean
    public QuartzInitializerListener executorListener() {
        return new QuartzInitializerListener();
    }

    /**
     * 解决:Job的创建是有Quartz通过反射创建的,并未交由Spring容器创建。故原则上来说,是无法在Job实例中使用依赖注入的。
     */
    public final class AutowiredSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
        /**
         * AutowireCapableBeanFactory: 是在BeanFactory的基础上实现对已存在实例的管理。
         * 可以使用这个接口集成其他框架,捆绑并填充并不由Spring管理生命周期并已存在的实例。
         * 参考: https://www.jianshu.com/p/14dd69b5c516
         */
        private AutowireCapableBeanFactory beanFactory;

        @Override
        public void setApplicationContext(ApplicationContext applicationContext) {
            this.beanFactory = applicationContext.getAutowireCapableBeanFactory();
        }

        @Override
        protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
            Object jobInstance = super.createJobInstance(bundle);
            beanFactory.autowireBean(jobInstance);
            return jobInstance;
        }
    }

}
/**
 * @Author: rhb
 * @Date: 2020/9/30 15:11
 * @Description: Job基础服务
 */
@Slf4j
@Service
@Transactional
public class JobBaseServiceImpl implements JobBaseService {

    @Autowired
    SchedulerFactoryBean schedulerFactoryBean;

    private Scheduler scheduler;

    @PostConstruct
    public void init(){
        this.scheduler = schedulerFactoryBean.getScheduler();
    }

    @Override
    public Result addJob(JobDTO jobDTO) {
        try {
            Class cla = Class.forName(jobDTO.getClassJobPath());

            JobDetail jobDetail = JobBuilder.newJob(cla)
                    .withIdentity(jobDTO.getClassJobName(),jobDTO.getClassJobGroup())
                    .withDescription(jobDTO.getClassJobDescription())
                    .storeDurably(true)
                    .build();

            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(jobDTO.getClassJobCron());

            Trigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity(jobDTO.getClassJobName(),jobDTO.getClassJobGroup())
                    .withDescription(jobDTO.getClassJobDescription())
                    .withSchedule(cronScheduleBuilder)
                    .build();

            scheduler.scheduleJob(jobDetail,trigger);
        } catch (ClassNotFoundException e) {
            log.info("Job基础服务 | 添加失败 | 类路径错误");
            Assert.isTrue(false,"类路径错误");
        } catch (SchedulerException e) {
            log.info("Job基础服务 | 添加失败 | cron表达式错误");
            Assert.isTrue(false,"cron表达式错误");
        }
        return ResultUtils.success("添加成功");
    }

    @Override
    public Result deleteJob(JobDTO jobDTO) {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(jobDTO.getClassJobName(), jobDTO.getClassJobGroup());
            JobKey jobKey = JobKey.jobKey(jobDTO.getClassJobName(),jobDTO.getClassJobGroup());

            scheduler.pauseTrigger(triggerKey);
            scheduler.unscheduleJob(triggerKey);
            scheduler.deleteJob(jobKey);
        } catch (SchedulerException e) {
            log.info("Job基础服务 | 删除失败 | "+e.getMessage());
            Assert.isTrue(false,e.getMessage());
        }
        return ResultUtils.success("删除成功");
    }

    @Override
    public Result rescheduleJob(JobDTO jobDTO) {
        TriggerKey triggerKey = TriggerKey.triggerKey(jobDTO.getClassJobName(),jobDTO.getClassJobGroup());

        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(jobDTO.getClassJobCron());

        try {
            CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);

            cronTrigger.getTriggerBuilder().withSchedule(cronScheduleBuilder).build();

            scheduler.rescheduleJob(triggerKey,cronTrigger);
        } catch (SchedulerException e) {
            log.info("Job基础服务 | 重启失败 | "+e.getMessage());
            Assert.isTrue(false,e.getMessage());
        }

        return ResultUtils.success("重启成功");
    }

    @Override
    public Result pauseJob(JobDTO jobDTO) {
        JobKey jobKey = JobKey.jobKey(jobDTO.getClassJobName(),jobDTO.getClassJobGroup());
        try {
            scheduler.pauseJob(jobKey);
        } catch (SchedulerException e) {
            log.info("Job基础服务 | 暂停失败 | "+e.getMessage());
            Assert.isTrue(false,e.getMessage());
        }
        return ResultUtils.success("暂停成功");
    }

    @Override
    public Result resumeJob(JobDTO jobDTO) {
        JobKey jobKey = JobKey.jobKey(jobDTO.getClassJobName(),jobDTO.getClassJobGroup());
        try {
            scheduler.resumeJob(jobKey);
        } catch (SchedulerException e) {
            log.info("Job基础服务 | 恢复失败 | "+e.getMessage());
            Assert.isTrue(false,e.getMessage());
        }
        return ResultUtils.success("恢复成功");
    }

}
        <!--quartz依赖-->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>com.zaxxer</groupId>
                    <artifactId>HikariCP-java7</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>

        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz-jobs</artifactId>
        </dependency>

        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
            <version>3.3.1</version>
        </dependency>

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java分布式调度框架是一种用于分布式系统中任务调度和资源管理的框架。以下是一些常见的Java分布式调度框架: 1. Apache Mesos:Apache Mesos是一个高效的分布式系统内核,它允许在大规模集群中高效运行各种应用程序。它提供了任务调度、资源分配、容错和服务发现等功能。 2. Apache Spark:Apache Spark是一个快速的通用集群计算系统,提供了内存计算和分布式任务调度等功能。它支持多种编程语言,包括Java,并且可以与Hadoop、Hive和HBase等相关生态系统集成。 3. Spring Cloud Data Flow:Spring Cloud Data Flow是一个用于构建和管理大规模数据处理和集成应用程序的分布式系统。它提供了任务调度、数据流管理、实时分析和批处理等功能,并且可以与Spring Boot和Spring Cloud等相关框架集成。 4. Apache Hadoop YARN:Apache Hadoop YARN是Hadoop框架的资源管理和任务调度系统。它通过将任务调度和资源管理分离,实现了更高的系统效率和灵活性。 5. Netflix Fenzo:Netflix Fenzo是一个用于任务调度和资源管理的开源库。它提供了灵活的调度算法和资源分配策略,可以与Mesos和Kubernetes等容器编排系统集成。 6. QuartzQuartz是一个开源的任务调度框架,用于在Java应用程序中执行定时和延迟任务。它支持复杂的调度需求,并且可以与多个任务执行器集成,包括集群和分布式环境。 这些框架提供了不同的功能和适用场景,可以根据具体的需求选择最适合的框架。无论是大规模数据处理、实时分析还是定时任务调度,都可以找到适合的Java分布式调度框架来支持。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值