宋现锋 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)来执行具体的操作。因为涉及具体的业务,就不在此粘贴代码了。
四, 总结
在具体的开发工作中,通过在网上查找相应的文章,加上自己的调试总结。充分证明上面代码是的效可用的,借助于前端用户交互效果,能很好地完成对定时任务的灵活操作,在此将相关的内容总结一下,希望对有需要的同学一点儿提示。