Quartz 定时任务管理

前言

       将项目中的所有定时任务都统一管理吧,使用 quartz 定时任务

设计思路

  1.  使用 quartz 的相关jar 包,懒得去升级了,我使用的是 quart 1.6
  2.  写一个定时任务管理类
  3.  用一张数据库表去统一定时任务
  4.  项目启动的时候也启动定时任务管理,同时启动开启状态的定时任务
  5. 制定页面去管理数据库的定时任务,如果,任务有修改删除停止等,修改对应修改定时任务
  6. 项目停止时,停止定时任务

部分实现代码 

数据库脚本

DROP TABLE IF EXISTS `sys_scheduler`;

CREATE TABLE `sys_scheduler` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `cron` varchar(255) NOT NULL DEFAULT '',
  `job_name` varchar(255) DEFAULT NULL,
  `job_class` varchar(255) NOT NULL DEFAULT '',
  `modify_time` datetime DEFAULT NULL,
  `is_start` char(1) DEFAULT '0' COMMENT '任务状态是否启动,1-启动中,0-未启动',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

/*Data for the table `sys_scheduler` */

insert  into `sys_scheduler`(`id`,`cron`,`job_name`,`job_class`,`modify_time`,`is_start`) values (1,'0 30 * * * ?','示例定时任务','com.common.job.ExampleJob','2016-05-06 16:42:14','0');

定时任务管理(数据库的操作类省略)

package com.common.utils;

import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;
import org.quartz.CronTrigger;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;

import com.common.dao.SysSchedulerDao;
import com.common.model.SysScheduler;

/**
 * 定时任务 管理类
 * @author ppnie
 *
 */
public class SchedulerManager
{
    static SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();
    static Scheduler sched = null;
    static SchedulerManager schedulerMgr = null;
    
    private static final Logger logger = Logger.getLogger(SchedulerManager.class.getName());
    
    /**
     * 创建定时任务单例,并且初始化启动定时任务
     * @return
     */
    public static SchedulerManager getInstance()
    {
        if (schedulerMgr == null)
        {
            schedulerMgr = new SchedulerManager();
            schedulerMgr.init();
        }
        return schedulerMgr;
    }
    
    /**
     * 初始化定时任务
     */
    public void init()
    {
        try
        {
            sched = schedFact.getScheduler();
        }
        catch (Exception e)
        {
            logger.error("init1:" + e.getMessage());
        }


        start();
        
        /*从数据库启动定时任务 */
        SysSchedulerDao ssdao = new SysSchedulerDao();
        List<SysScheduler> cdLists = ssdao.getSchedulerListByStart(ssdao.need_start);
        Iterator<SysScheduler> ir = cdLists.iterator();
        // System.out.println("-------------------Init Scheduler------------------");
        while (ir.hasNext())
        {
            SysScheduler scheduler = ir.next();
            scheduleJob(scheduler);
        }
        
    }
    
    public void scheduleJob(SysScheduler scheduler)
    {
        scheduleJob(""+scheduler.getId(),scheduler.getJobClass(),scheduler.getCron());
        if (isStarted())
        {
            System.out.println("Schedule " + scheduler.getJobName()+" class="+scheduler.getJobClass() + " cron=" + scheduler.getCron());
        }
    }
    
    /**
     * 添加某个任务到任务调度器
     * @param jobId  任务id
     * @param jobClass  任务job 类名
     * @param cron 定时时间
     * 设置定时器调度的时程表格式 秒 分 时 天 月 周 0 0 12 * * ? 每天中午十二点触发 0 15 10 15 * ? 每月15号的10:15触发 0 15 10 ? * 2-6
     * 每个周一、周二、周三、周四、周五的10:15触发
     */
    public void scheduleJob(String jobId, String jobClass, String cron)
    {
        if (isStarted())
        {
            try
            {
                Class cls = Class.forName(jobClass);
                
                JobDetail jobDetail = new JobDetail(jobId, Scheduler.DEFAULT_GROUP, cls);
                
                CronTrigger trigger = new CronTrigger(jobId, Scheduler.DEFAULT_GROUP, cron);
                
                sched.scheduleJob(jobDetail, trigger);
            }
            catch (Exception e)
            {
                System.out.println("scheduleJob这里报错"+jobClass);
                logger.error("scheduleJob:" + e.getMessage());
            }
        }
    }
    
    /**
     * 
     * @param jobId
     * @param jobClass
     * @param cron
     * @param data_map
     */
    public void scheduleJob(String jobId, String jobClass, String cron, String data_map)
    {
        if (isStarted())
        {
            System.out.println("Schedule " + jobClass + " cron=" + cron);
            try
            {
                Class cls = Class.forName(jobClass);
                
                JobDetail jobDetail = new JobDetail(jobId, Scheduler.DEFAULT_GROUP, cls);
                
                CronTrigger trigger = new CronTrigger(jobId, Scheduler.DEFAULT_GROUP, cron);
                
                sched.scheduleJob(jobDetail, trigger);
            }
            catch (Exception e)
            {
                logger.error("scheduleJob:" + e.getMessage());
            }
        }
    }
    
    /**
     * 根据jobId 在 任务调度器 中删除某个任务
     * @param jobId
     */
    public void delJob(String jobId)
    {
        try
        {
            sched.deleteJob(jobId, Scheduler.DEFAULT_GROUP);
        }
        catch (Exception e)
        {
            logger.error("deleteJob:" + e.getMessage());
        }
    }
    
    /**
     * 重新发布任务,在这里是根据jobId 修改任务执行时间 corn 
     * @param jobId
     * @param cron
     */
    public void rescheduleJob(String jobId, String cron)
    {
        try
        {            
            JobDetail jd = sched.getJobDetail(jobId, Scheduler.DEFAULT_GROUP);
            JobDataMap jdm = jd.getJobDataMap();
            CronTrigger trigger = new CronTrigger("" + jobId, Scheduler.DEFAULT_GROUP, cron);
            trigger.setJobName("" + jobId);
            trigger.setJobGroup(Scheduler.DEFAULT_GROUP);
            trigger.setJobDataMap(jdm);
            sched.rescheduleJob(jobId, Scheduler.DEFAULT_GROUP, trigger);
        }
        catch (Exception e)
        {
            logger.error("rescheduleJob:" + e);
        }
    }
    
    /**
     * 启动 任务调度器
     * 只有在Scheduler 有实例或standby 模式才能调用start() 方法
     */
    public void start()
    {
        try
        {
            sched.start();
        }
        catch (Exception e)
        {
            logger.error("start:" + e);
        }
    }
    
    /**
     * 关闭 任务调度器Scheduler
     * 一旦调用shutdown() 方法之后就不能在调用start() 方法
     */
    public void shutdown()
    {
        System.out.println("------------------Shutdown Scheduler------------------");
        try
        {
            sched.shutdown();
        }
        catch (Exception e)
        {
            logger.error("shutdown:" + e.getMessage());
        }
        schedulerMgr = null;
    }
    
    /**
     * 判断 任务调度器Scheduler 是否被启动
     * @return
     */
    public boolean isStarted()
    {
        boolean re = false;
        try
        {
            re = sched.isStarted();
        }
        catch (Exception e)
        {
            logger.error("isStarted:" + e.getMessage());
        }
        return re;
    }
    
    /**
     * 判断 任务调度器Scheduler 是否关闭
     * @return
     * @throws SchedulerException
     */
    public boolean isShutdown()
    {
        boolean re = false;
         try
        {
            sched.isShutdown();
        }
        catch (SchedulerException e)
        {
            logger.error("isShutdown:" + e.getMessage());
        }
        
        return re;
    }
    
    /**
     * 设置 Scheduler 为 standby 模式
     * standby 模式时 Scheduler 暂时停止查找 Job 去执行
     */
    public void standby() {
        System.out.println("------------------Standby Scheduler------------------");
        try {
            sched.standby();
        }
        catch (Exception e) {
            logger.error("standby:" + e.getMessage());
        }
    }

    /**
     * 判断Scheduler 操作是否是 standby 模式
     */
    public boolean isInStandbyMode() {
        boolean re = false;
        try {
            re = sched.isInStandbyMode();
        } catch (Exception e) {
            logger.error("isInStandbyMode:" + e.getMessage());
        }
        return re;
    }
    
    /**
     * 判断任务是否存在
     * @param jobId
     * @return
     */
    public boolean checkExists(String jobId)
    {
        boolean re = false;
        try
        {
            CronTrigger trigger = (CronTrigger)sched.getTrigger("" + jobId, Scheduler.DEFAULT_GROUP);
            return trigger != null;
        }
        catch (SchedulerException e)
        {
            logger.error("checkExists:" + e.getMessage());
        }

        return re;
    }
    
}

  

而随着项目的启停,可以建立一个servlet ,在init 方法中初始化 任务管理类,destory 方法中 关闭

  <servlet>
    <servlet-name>SysSchedulerServlet</servlet-name>
    <servlet-class>com.common.servlet.SysSchedulerServlet</servlet-class>
    <load-on-startup>0</load-on-startup>
  </servlet>

  

 

posted @ 2016-06-02 16:26  panie2015  阅读(1639)  评论(0编辑  收藏  举报