quartz实际使用

前言

之前写了一个quart指南,事后自己看都觉得十分的凌乱,不知从何下手,于是决定再写一篇,争取比上一篇写的好。

quartz优势

quartz实现了监听时钟,定时执行
quartz实现了持久化任务到数据库,并从数据库中读取数据定时执行
优化执行效率,多线程管理,配置线程池
等等

从一个实际的例子入手

需求
提供接口,实现
1. 调用可以立即执行一个service(其实这个不是quartz的优势)
2. 调用可以周期性执行一个service ,如果项目停掉,再重启可重新启动对这个servcie的调用
【注: 由于我用在ofbiz上,这个service是指ofbiz中的service,其实就是指一个具体实现某个业务的java方法,可替换修改】

分析

  1. 项目启动时应该吧执行job,监测trigger,的scheduler 启动起来(job和trigger分别是任务和触发器,不在详述,上一篇有说明)
  2. 启动后应该有两个方法供我们调用,分别实现上面的立即执行和周期性执行
  3. 配置quartz的数据库,以持久化job和trigger的数据,方便下次调用

实现
准备工作,官网下载quartz包,将里面的jar包导入到项目

1.在web.xml中配置了启动servlet,来启动scheduler

  <servlet>
        <servlet-name>SchedulerServlet</servlet-name>
        <servlet-class>cn.metasolo.manager.StartScheduler</servlet-class>
        <load-on-startup>1</load-on-startup>
  </servlet>

StartScheduler启动和停止

//继承HttpServlet 重写init()和destroy()方法
public class StartScheduler extends HttpServlet {

    /**
     * start quartz scheduler
     */
    private static Logger logger =LogManager.getLogger("quartz");
    private static final long serialVersionUID = 1L;
    public void init(){
        SchedulerManager.start();
        logger.info("[quart scheduler start]");
    }
    public void destroy(){
        SchedulerManager.shutdown();
        logger.info("[quart scheduler shutdown]");
    }
}

2.创建SchedulerManager来提供api
代码看起来有点长,只是包含了4个方法1个内部类,方法用途分别是:启动,停止,立即执行某个service,周期性执行某个service,内部类是用于实现Job的。
注:这里的delegator 和dispatcher 是ofbiz 中的一些工具类,你在用的时候完全可以去掉,把serviceName 想办法换成你的java方法调用。

import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;
import static org.quartz.CronScheduleBuilder.cronSchedule;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.ofbiz.entity.Delegator;
import org.ofbiz.entity.DelegatorFactory;
import org.ofbiz.service.GenericServiceException;
import org.ofbiz.service.LocalDispatcher;
import org.ofbiz.service.ServiceContainer;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleTrigger;
import org.quartz.impl.StdSchedulerFactory;


public class SchedulerManager {
    private static Logger logger =LogManager.getLogger("quartz");

    private static Scheduler sched;
    private static JobDetail job;
    private static CronTrigger trigger;
    private static Delegator delegate;
    private static LocalDispatcher dispatcher;

    public static void start() {
        try {
            SchedulerFactory sf = new StdSchedulerFactory();
            try {
                sched=sf.getScheduler();
                delegate = DelegatorFactory.getDelegator("default");
                dispatcher = ServiceContainer.getLocalDispatcher(delegate.getDelegatorName(), delegate);
            } catch (SchedulerException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            if(sched!=null&&!sched.isStarted()){
                sched.start();
            }
        } catch (SchedulerException e) {

            e.printStackTrace();
        }

    }

    public static void shutdown() {
        try {
            if(sched!=null&&!sched.isShutdown()){
                sched.shutdown();;
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }


    }
    /**
     * addJobRunCyclicity
     * @author xkl
     * @param serviceName
     * @param maps
     * @param cyclicity
     * <b>execute cyclicity</b>
     */
    public static void addJobRunCyclicity(String serviceName,Map<String, Object> maps,String cyclicity){
        //如果已经存在任务列表里,不再添加
        JobKey key = new JobKey(serviceName, "serviceGroup");
        try {
            if(sched.checkExists(key)){

                logger.info("This job is exists!add failed!");
                return;
            }
        } catch (SchedulerException e1) {
            logger.error("Check job key exists error:"+e1.getMessage());
        }
        job = newJob(ServiceJob.class).withIdentity(serviceName, "serviceGroup").build();
        job.getJobDataMap().put("conditions", maps);
        trigger = newTrigger().withIdentity("trigger_"+serviceName,"serviceGroup").startNow().withSchedule(cronSchedule(cyclicity)).build();
        try {
            sched.scheduleJob(job, trigger);
            logger.info("[execute service "+serviceName+" by  cyclicity of "+ cyclicity+"]");
        } catch (SchedulerException e) {
            logger.error("Add scheduler Job error:"+e.getMessage());
        }
    }
    /**
     * addJobRunImmediately
     * @param serviceName
     * @param maps
     *<p> execute immediately</p>
     */
    public static void addJobRunImmediately(String serviceName,Map<String, Object> maps){
        //如果已经存在任务列表里,不再添加
        JobKey key = new JobKey(serviceName, "serviceGroup");
        try {
            if(sched.checkExists(key)){
                logger.info("This job is exists!add failed!");
                return;
            }
        } catch (SchedulerException e1) {
            logger.error("Check job key exists error:"+e1.getMessage());
        }
        job = newJob(ServiceJob.class).withIdentity(serviceName, "serviceGroup").build();
        job.getJobDataMap().put("conditions", maps);
        SimpleTrigger trigger = (SimpleTrigger) newTrigger().withIdentity("trigger_"+serviceName, "group1").startNow().build();
        try {
            sched.scheduleJob(job, trigger);
            logger.info("[execute service "+serviceName+" immediately]");
        } catch (SchedulerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public static class ServiceJob implements Job{
        @Override
        public void execute(JobExecutionContext context) throws JobExecutionException {
            try {
                JobKey jobKey = context.getJobDetail().getKey();
                Map<String,Object> maps = context.getJobDetail().getJobDataMap();
                Map<String,Object> conditions = null;

                if(maps.get("conditions")!=null){
                    conditions = (Map<String,Object>)maps.get("conditions");
                }

                dispatcher.runSync(jobKey.getName(),conditions);
                logger.info("执行了ServiceJob任务");
            } catch (GenericServiceException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

    }
}

3.如何持久化:持久化需要配置数据库了,quart包中的 \quartz-2.2.3\docs\dbTables 目录中有初始化创建各种数据表的 sql 语句,根据你的需要创建不同的数据库以及 数据库表
我用的是tables_postgres.sql 不贴了,自己打开找一下吧

生成表后还需要配置一下quartz.properties配置文件:(名字不能改,放在classpath下)


#============================================================================
# Configure Main Scheduler Properties  
#============================================================================

org.quartz.scheduler.instanceName: SchedulerManager
org.quartz.scheduler.instanceId: AUTO

org.quartz.scheduler.skipUpdateCheck: true

#============================================================================
# Configure ThreadPool  
#============================================================================

org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 5
org.quartz.threadPool.threadPriority: 5

#============================================================================
# Configure JobStore  
#============================================================================

org.quartz.jobStore.misfireThreshold: 60000

#org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore

org.quartz.jobStore.class: org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass: org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
org.quartz.jobStore.useProperties: false
org.quartz.jobStore.dataSource: myDS
org.quartz.jobStore.tablePrefix: QRTZ_
org.quartz.jobStore.isClustered: false


#============================================================================
# Configure Datasources  
#============================================================================

org.quartz.dataSource.myDS.driver: org.postgresql.Driver
org.quartz.dataSource.myDS.URL: jdbc:postgresql://localhost/ErpQuartz
org.quartz.dataSource.myDS.user:****
org.quartz.dataSource.myDS.password:***
org.quartz.dataSource.myDS.maxConnections: 5

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Quartz 是一个流行的开源作业调度框架,支持按照时间表和条件来触发作业。KeepAliveJob 是 Quartz 内置的一个作业类型,它的作用是在指定时间间隔内执行一些操作,以保持应用程序的活跃状态。 下面是使用 C# 实现 KeepAliveJob 的示例代码: ```csharp using Quartz; using System; public class KeepAliveJob : IJob { public void Execute(IJobExecutionContext context) { // 在这里实现需要执行的操作 Console.WriteLine("KeepAliveJob is running at " + DateTime.Now.ToString()); } } public class JobScheduler { public static async Task Start() { // 创建作业调度器 StdSchedulerFactory factory = new StdSchedulerFactory(); IScheduler scheduler = await factory.GetScheduler(); // 创建 KeepAliveJob IJobDetail job = JobBuilder.Create<KeepAliveJob>() .WithIdentity("KeepAliveJob", "Group1") .Build(); // 创建触发器,每隔 5 秒钟执行一次 KeepAliveJob ITrigger trigger = TriggerBuilder.Create() .WithIdentity("KeepAliveTrigger", "Group1") .StartNow() .WithSimpleSchedule(x => x .WithIntervalInSeconds(5) .RepeatForever()) .Build(); // 将 KeepAliveJob 和触发器绑定到作业调度器上 await scheduler.ScheduleJob(job, trigger); // 开始执行作业调度器 await scheduler.Start(); } } ``` 在上面的示例中,我们定义了一个名为 KeepAliveJob 的作业类型,并在其中实现了需要执行的操作。然后,我们创建了一个作业调度器和一个 KeepAliveJob 实例,并将它们绑定到触发器上,以便在指定的时间间隔内执行。最后,我们启动了作业调度器,开始执行作业。 在实际应用中,你可以根据需要修改 KeepAliveJob 的实现,以便执行特定的操作,例如发送心跳包、检查数据库连接等。同时,你也可以根据实际需求调整触发器的执行时间间隔,以保持应用程序的活跃状态。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值