基於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();
    }

後言,以上所述都是在實際業務場景下,我花了兩個晚上的時間,搭建實現完了的一套系統
有需要的同學可以評論區留言或者發我郵箱來交流,相互進步,相互學習。

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