基于spring-quartz的动态数据源与异构任务调度中心设计

本篇主要讲基于 spring quartz的多数据源、动态数据源,多任务调度中心架构原理与实现,源码分享。

在企业应用中,很多服务都是依托数据来展开的,数据是各企业的核心资源之一。大量的业务场景产生大量的数据,这些数据要被各种工具进行加工处理,最后返哺整个业务链。定时任务是最常见的数据处理手段之一。任务调度场景几乎出现在所有的企业应用中,这些任务的调度在比较庞大的场景下,就显得不好管理,因此进行任务调度的总体集成,对其进行统一管理是不得不考虑的事情了。

一、场景

某个项目是由微服务构成,有四套数据源,有两套系统完全一致的环境用在几个不同的项目中,任务调度都在各自不同的微服务里面。造成的现状就是,在各应用系统里面,调度任务与业务系统揉合在一块,高度耦合。各任务调度的配置和执行显得臃肿累赘,代码的复用率极低,又因为几个项目又略有不同,导致依然存在有不同的调度任务,各系统之间的差异性开发、测试、部署等各软件生命周期中,大型的任务调度有可能严重影响业务系统效率。

二、目标

我们要构建一套任务调度中心,要实现以下几个核心内容

  • 首先要满足调度任务的常规基础需求,如:调度任务
  • 满足基础需求后,还要可以热加载,无缝切换等常规操作,如:实时修改调度计划、启动时间等等。
  • 支持多数据源、支持数据源动态切换、支持数据源热加载等等多数据源机制,如:一个模块实现不同数据源的切换,在线添加一个数据源并切换等等。
  • 分布式事务的处理,如:主程与子模块直接的事务一致。
  • 分布式请求转发与接口扩展,如,通过认证机制的支持,可以对目标接口执行计划调度请求等。

三、实现

架构依然采用springboot快速构架的优良特性来架构,DB使用mysql来实现,当让再这个体系下,数据库可以再多数据源机制的支持下,做到任何一种集成方式,任意的组合理论都是可以,只要你的架构能力足,这都不是问题,但是也要考虑系统复杂性等等成本的因素。 我选mybatis框架来支持持久层逻辑实现。采用OAuth2.0框架下的认证机制。事务和数据源你可以采用spring的或者你能力精力足够,你可以自己去开发一套,个人建议不要重复造轮子了,剩下来的其实就简单了,就是任务调度的配置、计划及其对应的持久化和唤起实现,再就是利用注解来切入,实现数据源的切换。至此,总体的实现方式基本就完了。

四、源码分析

工程结构
在这里插入图片描述
启动spring容器,需要监听一下spring的启动,来初始化调度任务列表,重写QuartzInitializerListener

@Bean
    public QuartzInitializerListener executorListener() {
        try {
            List<JobAndTrigger> list = iJobAndTriggerService.list();
            for (JobAndTrigger jat : list) {
                if (!CronExpression.isValidExpression(jat.getCronExpression())) {
                    continue;
                }
                BaseJob job = (BaseJob) Class.forName(jat.getJobClassName()).newInstance();
                JobDetail jobDetail = JobBuilder.newJob(job.getClass()).
                        withIdentity(jat.getJobClassName(), jat.getTriggerGroup())
                        .build();

                //表达式调度构建器(即任务执行的时间)
                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(jat.getCronExpression());
                //按新的cronExpression表达式构建一个新的trigger
                CronTrigger trigger = TriggerBuilder.newTrigger().
                        withIdentity(jat.getJobClassName(), jat.getTriggerGroup())
                        .withSchedule(scheduleBuilder)
                        .build();
                scheduler().scheduleJob(jobDetail, trigger);
            }
            log.info("=========avatar.wlgdo|quartz jobs begined======");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new QuartzInitializerListener();
    }

后言,以上所述都是在实际业务场景下,我花了两个晚上的时间,搭建实现完了的一套系统
有需要的同学可以评论区留言或者发我邮箱来交流,相互进步,相互学习。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章