最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

可視化定時(shí)任務(wù)quartz集成解析全過程

 更新時(shí)間:2022年10月21日 11:19:38   作者:小鮑侃java  
在開發(fā)中有很多定時(shí)任務(wù)都不是寫死的而是可以人為配置并且寫到數(shù)據(jù)庫中的,下面這篇文章主要給大家介紹了關(guān)于可視化定時(shí)任務(wù)quartz集成解析的相關(guān)資料,需要的朋友可以參考下

前言

在日常的工作中,定時(shí)任務(wù)也是一個非常常見的需求,可以使用注解實(shí)現(xiàn),但是使用這種方式有幾個問題,首先就是如果修改比較麻煩,而且沒有提供特定的頁面對定時(shí)任務(wù)進(jìn)行可視化管理。所以quartz就應(yīng)運(yùn)而生。本文將介紹如何實(shí)現(xiàn)springboot與quartz的整合。

1.目錄結(jié)構(gòu)

配置類 配置SchedulerFactory固化定時(shí)任務(wù)和日志的業(yè)務(wù)類定時(shí)任務(wù)類運(yùn)行配置

2.原理

  1. scheduler是一個計(jì)劃調(diào)度器容器(總部),容器里面可以盛放眾多的JobDetail和trigger,當(dāng)容器啟動后,里面的每個JobDetail都會根據(jù)trigger按部就班自動去執(zhí)行。
  2. JobDetail是一個可執(zhí)行的工作,它本身可能是有狀態(tài)的。
  3. Trigger代表一個調(diào)度參數(shù)的配置,什么時(shí)候去調(diào)。
  4. 當(dāng)JobDetail和Trigger在scheduler容器上注冊后,形成了裝配好的作業(yè)(JobDetail和Trigger所組成的一對兒),就可以伴隨容器啟動而調(diào)度執(zhí)行了。
  5. scheduler是個容器,容器中有一個線程池,用來并行調(diào)度執(zhí)行每個作業(yè),這樣可以提高容器效率

3.表結(jié)構(gòu)

自帶有11張系統(tǒng)表和2張業(yè)務(wù)表(自建),其中綠色為自己建立的表

4.整合springboot

1.pom文件

        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.2.1</version>
        </dependency>

2.ScheduleConfig

配置工廠類的參數(shù)。

@Configuration
public class ScheduleConfig {
 
	@Bean
	public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) {
		SchedulerFactoryBean factory = new SchedulerFactoryBean();
		factory.setDataSource(dataSource);
		// quartz參數(shù)
		Properties prop = new Properties();
		prop.put("org.quartz.scheduler.instanceName", "QUARTZ");
		prop.put("org.quartz.scheduler.instanceId", "AUTO");
		// 線程池配置
		prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
		prop.put("org.quartz.threadPool.threadCount", "20");
		prop.put("org.quartz.threadPool.threadPriority", "5");
		// JobStore配置
		prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
		// 集群配置
		prop.put("org.quartz.jobStore.isClustered", "true");
		prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000");
		prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");
		prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true");
		// sqlserver 啟用
		prop.put("org.quartz.jobStore.misfireThreshold", "12000");
		prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
		factory.setQuartzProperties(prop);
		factory.setSchedulerName("QUARTZ");
		// 延時(shí)啟動
		factory.setStartupDelay(1);
		factory.setApplicationContextSchedulerContextKey("applicationContextKey");
		// 可選,QuartzScheduler
		// 啟動時(shí)更新己存在的Job,這樣就不用每次修改targetObject后刪除qrtz_job_details表對應(yīng)記錄了
		factory.setOverwriteExistingJobs(true);
		// 設(shè)置自動啟動,默認(rèn)為true
		factory.setAutoStartup(true);
		return factory;
	}
}

3.業(yè)務(wù)類

主要是為頁面提供接口。

@RestController
@RequestMapping("/qrtzJob")
public class QrtzJobController {
 
    @Autowired
    private QrtzJobService qrtzJobService;
 
    /**
     * 檢查表達(dá)式
     * 
     * @param cron
     * @return
     */
    @GetMapping("/check")
    public boolean checkCron(String cron) {
        try {
            return CronExpression.isValidExpression(cron);
        } catch (Exception e) {
            return false;
        }
    }
 
    /**
     * 通過對象查詢數(shù)據(jù)
     *
     * @param qrtzJobVO 請求對象
     * @return 數(shù)據(jù)集合
     */
    @GetMapping("/selectQrtzJob")
    @ApiOperation(value = "通過實(shí)體查詢", notes = "通過實(shí)體查詢")
    public Result<List<QrtzJobVO>>
        selectQrtzJob(@ApiParam(name = "入?yún)ο?, value = "實(shí)體", required = false) QrtzJobVO qrtzJobVO) {
        Result<List<QrtzJobVO>> resultVO = new Result<>();
        // 業(yè)務(wù)查詢
        List<QrtzJobVO> resultListQrtzJob = qrtzJobService.queryQrtzJobAll(qrtzJobVO);
        resultVO.setData(resultListQrtzJob);
        return resultVO;
    }
 
    /**
     * 通過對象增加數(shù)據(jù)
     *
     * @param qrtzJobVO 請求對象
     * @return
     */
    @PostMapping("/createQrtzJob")
    @ApiOperation(value = "通過實(shí)體添加", notes = "通過實(shí)體添加")
    public Result
        createQrtzJob(@ApiParam(name = "入?yún)ο?, value = "實(shí)體", required = false) @RequestBody QrtzJobVO qrtzJobVO) {
        Result resultVO = new Result();
        // 業(yè)務(wù)處理
        qrtzJobService.createScheduleJob(qrtzJobVO);
        return resultVO;
    }
 
    /**
     * 通過對象修改
     *
     * @param qrtzJobVO 請求對象
     * @return
     */
    @PutMapping("/updateQrtzJob")
    @ApiOperation(value = "通過實(shí)體修改", notes = "通過實(shí)體修改")
    public Result
        updateQrtzJob(@ApiParam(name = "入?yún)ο?, value = "實(shí)體", required = false) @RequestBody QrtzJobVO qrtzJobVO) {
        Result resultVO = new Result();
        // 業(yè)務(wù)處理
        qrtzJobService.updateScheduleJob(qrtzJobVO);
        return resultVO;
    }
 
    /**
     * 通過對象刪除
     *
     * @param qrtzJobVO 請求對象
     * @return
     */
    @DeleteMapping("/deleteQrtzJob")
    @ApiOperation(value = "通過實(shí)體刪除", notes = "通過實(shí)體刪除")
    public Result
        deleteQrtzJob(@ApiParam(name = "入?yún)ο?, value = "實(shí)體", required = false) @RequestBody QrtzJobVO qrtzJobVO) {
        Result resultVO = new Result();
        // 業(yè)務(wù)處理
        qrtzJobService.deleteScheduleJob(qrtzJobVO);
        return resultVO;
    }
 
    /**
     * 運(yùn)行定時(shí)任務(wù)
     * 
     * @param qrtzJobVO
     * @return
     */
    @GetMapping("/runJob")
    public Result
        runJob(@ApiParam(name = "入?yún)ο?, value = "實(shí)體", required = false) @RequestBody List<QrtzJobVO> qrtzJobVO) {
        Result resultVO = new Result();
        // 業(yè)務(wù)處理
        qrtzJobService.run(qrtzJobVO);
        return resultVO;
    }
 
    /**
     * 暫停定時(shí)任務(wù)
     * 
     * @param qrtzJobVO
     * @return
     */
    @GetMapping("/pauseJob")
    public Result
        pauseJob(@ApiParam(name = "入?yún)ο?, value = "實(shí)體", required = false) @RequestBody List<QrtzJobVO> qrtzJobVO) {
        Result resultVO = new Result();
        // 業(yè)務(wù)處理
        qrtzJobService.pause(qrtzJobVO);
        return resultVO;
    }
 
    @GetMapping("resumeJob")
    public Result
        resumeJob(@ApiParam(name = "入?yún)ο?, value = "實(shí)體", required = false) @RequestBody List<QrtzJobVO> qrtzJobVO) {
        Result resultVO = new Result();
        // 業(yè)務(wù)處理
        qrtzJobService.resume(qrtzJobVO);
        return resultVO;
    }
 
}

4.運(yùn)行配置

ScheduleUtils:將新添加的trigger,jobDetail放入scheduler中。

public class ScheduleUtils {
 
    private static final Logger log = LoggerFactory.getLogger(ScheduleUtils.class);
 
    private static final String JOB_NAME_PREFIX = "TASK_";
 
    private static TriggerKey getTriggerKey(Long jobId) {
        return TriggerKey.triggerKey("TASK_" + jobId);
    }
 
    private static JobKey getJobKey(Long jobId) {
        return JobKey.jobKey("TASK_" + jobId);
    }
 
    public static CronTrigger getCronTrigger(Scheduler scheduler, Long jobId) {
        try {
            return (CronTrigger)scheduler.getTrigger(getTriggerKey(jobId));
        } catch (SchedulerException e) {
            log.error("獲取Cron表達(dá)式失敗", e);
            return null;
        }
    }
 
    public static void createScheduleJob(Scheduler scheduler, QrtzJobVO scheduleJob) {
        try {
            JobDetail jobDetail = JobBuilder.newJob(com.job.util.ScheduleJob.class)
                .withIdentity(getJobKey(scheduleJob.getJobId())).build();
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression())
                .withMisfireHandlingInstructionDoNothing();
            CronTrigger trigger = (CronTrigger)TriggerBuilder.newTrigger()
                .withIdentity(getTriggerKey(scheduleJob.getJobId())).withSchedule(scheduleBuilder).build();
            jobDetail.getJobDataMap().put("JOB_PARAM_KEY", scheduleJob);
            scheduler.scheduleJob(jobDetail, trigger);
            if (scheduleJob.getStatus().equals(CommonConstant.QUARTZ_PAUSE)) {
                pauseJob(scheduler, scheduleJob.getJobId());
            }
        } catch (SchedulerException e) {
            log.error("創(chuàng)建定時(shí)任務(wù)失敗", e);
        }
    }
 
    public static void updateScheduleJob(Scheduler scheduler, QrtzJobVO scheduleJob) {
        try {
            TriggerKey triggerKey = getTriggerKey(scheduleJob.getJobId());
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression())
                .withMisfireHandlingInstructionDoNothing();
            CronTrigger trigger = getCronTrigger(scheduler, scheduleJob.getJobId());
            if (trigger == null) {
                throw new SchedulerException("獲取Cron表達(dá)式失敗");
            }
            trigger =
                (CronTrigger)trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
            trigger.getJobDataMap().put("JOB_PARAM_KEY", scheduleJob);
            scheduler.rescheduleJob(triggerKey, trigger);
            if (scheduleJob.getStatus().equals(CommonConstant.QUARTZ_PAUSE)) {
                pauseJob(scheduler, scheduleJob.getJobId());
            }
        } catch (SchedulerException e) {
            log.error("更新定時(shí)任務(wù)失敗", e);
        }
    }
 
    public static void run(Scheduler scheduler, QrtzJobVO scheduleJob) {
        try {
            JobDataMap dataMap = new JobDataMap();
            dataMap.put("JOB_PARAM_KEY", scheduleJob);
            scheduler.triggerJob(getJobKey(scheduleJob.getJobId()), dataMap);
        } catch (SchedulerException e) {
            log.error("執(zhí)行定時(shí)任務(wù)失敗", e);
        }
    }
 
    public static void pauseJob(Scheduler scheduler, Long jobId) {
        try {
            scheduler.pauseJob(getJobKey(jobId));
        } catch (SchedulerException e) {
            log.error("暫停定時(shí)任務(wù)失敗", e);
        }
    }
 
    public static void resumeJob(Scheduler scheduler, Long jobId) {
        try {
            scheduler.resumeJob(getJobKey(jobId));
        } catch (SchedulerException e) {
            log.error("恢復(fù)定時(shí)任務(wù)失敗", e);
        }
    }
 
    public static void deleteScheduleJob(Scheduler scheduler, Long jobId) {
        try {
            scheduler.deleteJob(getJobKey(jobId));
        } catch (SchedulerException e) {
            log.error("刪除定時(shí)任務(wù)失敗", e);
        }
    }
}

5.ScheduleJob 

用于執(zhí)行定時(shí)任務(wù)。

public class ScheduleJob extends QuartzJobBean {
 
    private static final Logger log = LoggerFactory.getLogger(ScheduleJob.class);
 
    private ExecutorService service = Executors.newSingleThreadExecutor();
 
    @Override
    protected void executeInternal(JobExecutionContext context) {
        QrtzJobVO scheduleJob = (QrtzJobVO)context.getMergedJobDataMap().get("JOB_PARAM_KEY");
        QrtzJobLogService scheduleJobLogService = (QrtzJobLogService) SpringContextUtil.getBean(QrtzJobLogService.class);
        QrtzJobLogVO jobLog = new QrtzJobLogVO();
        jobLog.setJobId(scheduleJob.getJobId());
        jobLog.setBeanName(scheduleJob.getBeanName());
        jobLog.setMethodName(scheduleJob.getMethodName());
        if (CommonUtil.isEmpty(scheduleJob.getParams())) {
            jobLog.setParams("");
        } else {
            jobLog.setParams(scheduleJob.getParams());
        }
        long startTime = System.currentTimeMillis();
        try {
            log.info("任務(wù)準(zhǔn)備執(zhí)行,任務(wù)ID:{}", scheduleJob.getJobId());
            ScheduleRunnable task =
                new ScheduleRunnable(scheduleJob.getBeanName(), scheduleJob.getMethodName(), scheduleJob.getParams());
            Future<?> future = this.service.submit(task);
            future.get();
            long times = System.currentTimeMillis() - startTime;
            jobLog.setTimes(Long.valueOf(times));
            jobLog.setStatus("0");
            log.info("任務(wù)執(zhí)行完畢,任務(wù)ID:{} 總共耗時(shí):{} 毫秒", scheduleJob.getJobId(), Long.valueOf(times));
        } catch (Exception e) {
            log.error("任務(wù)執(zhí)行失敗,任務(wù)ID:" + scheduleJob.getJobId(), e);
            long times = System.currentTimeMillis() - startTime;
            jobLog.setTimes(Long.valueOf(times));
            jobLog.setStatus("1");
            jobLog.setError(StringUtils.substring(e.toString(), 0, 2000));
        } finally {
            scheduleJobLogService.insertQrtzJobLog(jobLog);
        }
    }
}

6.ScheduleRunnable

通過反射回去需要調(diào)用的類與方法。

public class ScheduleRunnable implements Runnable {
 
    private static final Logger log = LoggerFactory.getLogger(ScheduleRunnable.class);
 
    private Object target;
 
    private Method method;
 
    private String params;
 
    ScheduleRunnable(String beanName, String methodName, String params)
        throws NoSuchMethodException, SecurityException {
        this.target = SpringContextUtil.getBean(beanName);
        this.params = params;
        if (StringUtils.isNotBlank(params)) {
            this.method = this.target.getClass().getDeclaredMethod(methodName, new Class[] {String.class});
        } else {
            this.method = this.target.getClass().getDeclaredMethod(methodName, new Class[0]);
        }
    }
 
    @Override
    public void run() {
        try {
            ReflectionUtils.makeAccessible(this.method);
            if (StringUtils.isNotBlank(this.params)) {
                this.method.invoke(this.target, new Object[] {this.params});
            } else {
                this.method.invoke(this.target, new Object[0]);
            }
        } catch (Exception e) {
            log.error("執(zhí)行定時(shí)任務(wù)失敗", e);
        }
    }
}

5.使用

調(diào)用以上接口 ,參數(shù)如下。

    "beanName":"任務(wù)類",
    "methodName":"任務(wù)方法",
    "params":"參數(shù)",
    "cronExpression":"表達(dá)式",

總結(jié)

到此這篇關(guān)于可視化定時(shí)任務(wù)quartz集成解析的文章就介紹到這了,更多相關(guān)quartz集成解析內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • IntelliJ IDEA失焦自動重啟服務(wù)的解決方法

    IntelliJ IDEA失焦自動重啟服務(wù)的解決方法

    在使用 IntelliJ IDEA運(yùn)行 SpringBoot 項(xiàng)目時(shí),你可能會遇到一個令人困擾的問題,一旦你的鼠標(biāo)指針離開當(dāng)前IDE窗口,點(diǎn)擊其他位置時(shí), IDE 窗口會失去焦點(diǎn),你的 SpringBoot 服務(wù)就會自動重啟,所以本文給大家介紹了IntelliJ IDEA失焦自動重啟服務(wù)的解決方法
    2023-10-10
  • Springboot整合Spring Cloud Kubernetes讀取ConfigMap支持自動刷新配置的教程

    Springboot整合Spring Cloud Kubernetes讀取ConfigMap支持自動刷新配置的教程

    這篇文章主要介紹了Springboot整合Spring Cloud Kubernetes讀取ConfigMap支持自動刷新配置,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Java服務(wù)端服務(wù)監(jiān)控:Prometheus與Spring Boot Actuator的集成方式

    Java服務(wù)端服務(wù)監(jiān)控:Prometheus與Spring Boot Actuator的集成方式

    本文介紹了如何將Prometheus與SpringBootActuator集成,實(shí)現(xiàn)對Java服務(wù)端應(yīng)用的監(jiān)控,通過集成,可以利用Prometheus的強(qiáng)大監(jiān)控能力,及時(shí)發(fā)現(xiàn)和解決性能問題
    2024-12-12
  • MyBatis實(shí)現(xiàn)多表聯(lián)查的詳細(xì)代碼

    MyBatis實(shí)現(xiàn)多表聯(lián)查的詳細(xì)代碼

    這篇文章主要介紹了MyBatis如何實(shí)現(xiàn)多表聯(lián)查,通過實(shí)例代碼給大家介紹使用映射配置文件實(shí)現(xiàn)多表聯(lián)查,使用注解的方式實(shí)現(xiàn)多表聯(lián)查,需要的朋友可以參考下
    2022-08-08
  • Gradle構(gòu)建多模塊項(xiàng)目的方法步驟

    Gradle構(gòu)建多模塊項(xiàng)目的方法步驟

    這篇文章主要介紹了Gradle構(gòu)建多模塊項(xiàng)目的方法步驟,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • Spring?Boot中KafkaListener的介紹、原理和使用方法案例詳解

    Spring?Boot中KafkaListener的介紹、原理和使用方法案例詳解

    本文介紹了Spring Boot中 @KafkaListener 注解的介紹、原理和使用方法,通過本文的介紹,我們希望讀者能夠更好地理解Spring Boot中 @KafkaListener 注解的使用方法,并在項(xiàng)目中更加靈活地應(yīng)用
    2023-09-09
  • Java面試題沖刺第二十八天--數(shù)據(jù)庫(5)

    Java面試題沖刺第二十八天--數(shù)據(jù)庫(5)

    這篇文章主要為大家分享了最有價(jià)值的三道關(guān)于數(shù)據(jù)庫的面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Springboot+netty實(shí)現(xiàn)Web聊天室

    Springboot+netty實(shí)現(xiàn)Web聊天室

    這篇文章主要介紹了利用springboot+netty實(shí)現(xiàn)一個簡單Web聊天室,文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)Java的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-12-12
  • java的socket請求和響應(yīng)方式

    java的socket請求和響應(yīng)方式

    這篇文章主要介紹了java的socket請求和響應(yīng)方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • Java如何自定義線程池中隊(duì)列

    Java如何自定義線程池中隊(duì)列

    這篇文章主要介紹了Java如何自定義線程池中隊(duì)列,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-07-07

最新評論

临清市| 贺兰县| 珲春市| 潼关县| 若尔盖县| 徐闻县| 营山县| 洛南县| 乡城县| 南雄市| 丁青县| 民乐县| 千阳县| 昌邑市| 英吉沙县| 吉林市| 林口县| 会东县| 泽州县| 平武县| 潍坊市| 临洮县| 成武县| 黑水县| 江华| 保山市| 高唐县| 汕尾市| 正蓝旗| 天全县| 林周县| 祥云县| 巴南区| 江永县| 黄龙县| 顺平县| 哈密市| 德兴市| 柳州市| 丰县| 迁安市|