灵活操作Java定时任务

时间:2023-02-15 07:50:01

宋现锋 2018/2/6

在开发测试平台的时候,有很多情况下需要用到定时任务,如接口或是服务的监控,页面定时扫描,自动化测试用例定时执行等等。通常的做法是利用Jenkins做定时调用,也可以借助于Linux的定时任务crontab来设置要执行的任务。先前我使用python开发测试平台的时候,就是直接操作/var/spool/cron/root进行定时任务的添加,删除,开启和暂停的。可是最近用java借助于公司的SCF+WF框架进行测试平台的开发的时候,发现存在着问题:

1,    直接通过命令行方式执行java文件比较麻烦,因为需要执行的文件要调用很多包。

2,    而任何对定时任务的操作,如增加和删除都是比较麻烦的,需要先编译才能执行。

所以直接执行java文件的方法行不通,于是去网上搜索java处理定时任务的方法。这一搜还是挺多的,具体对考文章:https://www.cnblogs.com/wenbronk/p/6433178.html,为了更加灵活地满足动态操作定时任务的需要,我决定使用Quartz。下面我将具体的使用详细介绍一下:

一,  添加maven依赖

    将下面的依赖添加到你的maven工程的pom.xml文件中:

<dependency>

<groupId>org.quartz-scheduler</groupId>

<artifactId>quartz</artifactId>

<version>2.3.0</version>

</dependency>

  

二,  编写定时任务操作类

  下面的类中我添加了对定时任务操作的增,删,改,开启,停止等操作,代码中的注释比较全,很容易读懂的。

package com.bj58.qa.comtestplatform.web.bll.Admonitorbll;

import java.util.List;

import org.quartz.CronScheduleBuilder;

import org.quartz.CronTrigger;

import org.quartz.Job;

import org.quartz.JobBuilder;

import org.quartz.JobDetail;

import org.quartz.JobKey;

import org.quartz.Scheduler;

import org.quartz.SchedulerException;

import org.quartz.SchedulerFactory;

import org.quartz.Trigger;

import org.quartz.TriggerBuilder;

import org.quartz.TriggerKey;

import org.quartz.impl.StdSchedulerFactory;

 

public class CronTabOperationsBll

{

  private static SchedulerFactory schedulerFactory = new StdSchedulerFactory();

 

  /**

   * @Description: 添加一个定时任务

   * 

   * @param jobName 任务名

   * @param jobGroupName  任务组名

   * @param triggerName 触发器名

   * @param triggerGroupName 触发器组名

   * @param jobClass  任务

   * @param cron   时间设置,参考quartz说明文档 

   * @param clid:定时任务ID

   */ 

  public static void addJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName, Class jobClass, String cron, String clid)

  {

    try

    {

      Scheduler sched = schedulerFactory.getScheduler();

     

      JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();

      jobDetail.getJobDataMap().put("clid", clid);

     

      TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();

     

      triggerBuilder.withIdentity(triggerName, triggerGroupName);

      triggerBuilder.startNow();

     

      triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));

     

      CronTrigger trigger = (CronTrigger)triggerBuilder.build();

     

 

      sched.scheduleJob(jobDetail, trigger);

      if (!sched.isShutdown()) {

        sched.start();

      }

    }

    catch (Exception e)

    {

      throw new RuntimeException(e);

    }

  }

 

  /**

   * @Description: 编辑一个定时任务

   * 

   * @param jobName 任务名

   * @param jobGroupName  任务组名

   * @param triggerName 触发器名

   * @param triggerGroupName 触发器组名

   * @param cron   时间设置,参考quartz说明文档 

   * @param clid:定时任务ID

   */ 

  public static void modifyJobTime(String jobName, String jobGroupName, String triggerName, String triggerGroupName, String cron, String clid)

  {

    try

    {

      Scheduler sched = schedulerFactory.getScheduler();

      JobDetail jobDetail = sched.getJobDetail(JobKey.jobKey(jobName, jobGroupName));

      Class<? extends Job> jobClass = jobDetail.getJobClass();

      removeJob(jobName, jobGroupName, triggerName, triggerGroupName);

      addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, cron, clid);

    }

    catch (Exception e)

    {

      throw new RuntimeException(e);

    }

  }

  /**

   * @Description: 删除一个定时任务

   * 

   * @param jobName 任务名

   * @param jobGroupName  任务组名

   * @param triggerName 触发器名

   * @param triggerGroupName 触发器组名

   */ 

  public static void removeJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName)

  {

    try

    {

      Scheduler sched = schedulerFactory.getScheduler();

     

      TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);

     

      sched.pauseTrigger(triggerKey);

      sched.unscheduleJob(triggerKey);

      sched.deleteJob(JobKey.jobKey(jobName, jobGroupName));

    }

    catch (Exception e)

    {

      throw new RuntimeException(e);

    }

  }

 

  /**

   * 启动所有定时任务

   */

  public static void startJobs()

  {

    try

    {

      Scheduler sched = schedulerFactory.getScheduler();

      sched.start();

    }

    catch (Exception e)

    {

      throw new RuntimeException(e);

    }

  }

 

  /**

   *关闭所有定时任务

   */

  public static void shutdownJobs()

  {

    try

    {

      Scheduler sched = schedulerFactory.getScheduler();

      if (!sched.isShutdown()) {

        sched.shutdown();

      }

    }

    catch (Exception e)

    {

      throw new RuntimeException(e);

    }

  }

 

  /**

   * 关闭定时任务

   * @param jobName 任务名

   * @param jobGroupName  任务组名

   */

  public static void ShutDownJob(String jobName, String jobGroupName)

  {

    try

    {

      Scheduler scheduler = schedulerFactory.getScheduler();

      JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);

      scheduler.pauseJob(jobKey);

      System.out.println("关闭定时任务:" + jobName);

    }

    catch (SchedulerException e)

    {

      e.printStackTrace();

    }

  }

  /**

   * 开启一个定时任务

   * @param jobName 任务名

   * @param jobGroupName  任务组名

   */

  public static void StartJob(String jobName, String jobGroupName)

  {

    try

    {

      Scheduler scheduler = schedulerFactory.getScheduler();

      JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);

      scheduler.resumeJob(jobKey);

      System.out.println("开启定时任务:" + jobName);

    }

    catch (SchedulerException e)

    {

      e.printStackTrace();

    }

  }

  /**

   * 获取定时任务中存在的任务

   * @return

   */

  public static String GetAllExcutingJobs()

  {

    String jobslist = "定时任务中存在的JobGroups:";

    try

    {

      Scheduler scheduler = schedulerFactory.getScheduler();

      List<String> jobgroups = scheduler.getJobGroupNames();

      System.out.println("定时任务中存在的Jobs:" + jobgroups.size());

      for (String jbgroup : jobgroups) {

        jobslist = jobslist + "JobGroup:" + jbgroup;

      }

    }

    catch (SchedulerException e)

    {

      e.printStackTrace();

    }

    return jobslist;

  }

 

  /**

   * 获取定时任务的状态

   * @param triggerName 触发器名

   * @param triggerGroupName 触发器组名

   * @return

   */

  public static String GetJobStatus(String triggerName, String triggerGroupName)

  {

    String jobstatus = "定时任务" + triggerName + "的状态是:";

    try

    {

      Scheduler scheduler = schedulerFactory.getScheduler();

      TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);

      Trigger.TriggerState state = scheduler.getTriggerState(triggerKey);

      jobstatus = jobstatus + state;

    }

    catch (SchedulerException e)

    {

      e.printStackTrace();

    }

    return jobstatus;

  }

 

  public static void main(String[] args)

  {

    try

    {

      System.out.println("【系统启动】开始(每1秒输出一次)...");

      addJob("测试定时任务", "测试分组", "测试触发器", "测试触发器分组", CronTabTask.class, "0/1 * * * * ?", "9527");

      addJob("测试定时任务1", "测试分组1", "测试触发器1", "测试触发器分组1", CronTabTask.class, "0/2 * * * * ?", "850318");

      System.out.println(GetJobStatus("测试触发器", "测试触发器分组"));

     

      Thread.sleep(5000L);

      ShutDownJob("测试定时任务1", "测试分组1");

      System.out.println(GetJobStatus("测试触发器1", "测试触发器分组1"));

    }

    catch (Exception e)

    {

      e.printStackTrace();

    }

  }

}

  

   将这个类添加到公用包中,在需要操作定时任务的地方进行灵活调用,即可完成你的需求。注意说明的一点是:我的定时任务比较复杂,需要借助于”clid”来执行后续操作,所以在添加的时候需要传参数来给定时任务。传参数的语句如下:

jobDetail.getJobDataMap().put("clid", clid);

三,  定时任务执行类

   通过编写下面的类来执行具体的定时任务:

package com.bj58.qa.comtestplatform.web.bll.Admonitorbll;

 

import com.bj58.ershou.common.helper.LoggerHelper;

import java.io.PrintStream;

import java.util.Date;

import org.quartz.Job;

import org.quartz.JobDataMap;

import org.quartz.JobDetail;

import org.quartz.JobExecutionContext;

import org.quartz.JobExecutionException;

 

public class CronTabTask implements Job

{

  private static LoggerHelper loggerHelper = new LoggerHelper(CronTabTask.class);

  /**

   * 执行监控任务的定时任务

   */

  public void execute(JobExecutionContext jobExecutionContext)

    throws JobExecutionException

  {

    String clid = jobExecutionContext.getJobDetail().getJobDataMap().getString("clid");

    AdMonitorCronTab amct = new AdMonitorCronTab();

    amct.AdMonitorTask(clid);

    System.out.println(new Date() + ": 执行广告监控任务,任务ID:" + clid);

  }

}

  

而这个类中的AdMonitorCronTab才是我具体需要监控的内容,通过调用AdMonitorTask(clid)来执行具体的操作。因为涉及具体的业务,就不在此粘贴代码了。

四,  总结

    在具体的开发工作中,通过在网上查找相应的文章,加上自己的调试总结。充分证明上面代码是的效可用的,借助于前端用户交互效果,能很好地完成对定时任务的灵活操作,在此将相关的内容总结一下,希望对有需要的同学一点儿提示。