package com.sanyi.collect.service.job;
import com.sanyi.entity.SyTask;
import com.sanyi.collect.entity.vo.RunTaskVO;
import com.sanyi.collect.entity.vo.SyTaskVO;
import com.sanyi.collect.enums.EnableStatusEnum;
import com.sanyi.collect.enums.RunTaskTypeEnum;
import com.sanyi.enums.TaskActionEnum;
import com.sanyi.collect.service.SyTaskService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* @author ceshi
* @Description 作业基类
* @date 2021/6/2510:40
*/
@Component
@Slf4j
public class BaseBizJob {
/**
* id标识
*/
private static final long BEAT_JOB_ID = 1L;
/**
* 默认用户名
*/
private static final String TASK_USER = "System";
@Autowired
BizManageJob bizManageJob;
@Autowired
SyTaskService syTaskService;
/**
* 运行
*
* @param jobExecutionContext
* @return void
* @throws
* @author sunwy
* @date 2021/11/2
*/
protected void run(JobExecutionContext jobExecutionContext) {
try {
JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
Object obj = jobDataMap.get("taskId");
SyTaskVO syTaskVO = (SyTaskVO) obj;
//传递参数是否为空
if (syTaskVO == null) {
log.info("JobDataMap is null");
return;
}
//是否心跳任务
log.info("{} start at:{}", syTaskVO.getTaskName(), new Date());
if (syTaskVO.getId() == BEAT_JOB_ID) {
log.info("beat job ...");
return;
}
//业务逻辑
SyTask task = syTaskService.getById(syTaskVO.getId());
if (task == null) {
log.info("该任务已删除:{}", syTaskVO.getTaskName());
return;
}
//任务状态是否禁用
if (task.getStatus() != null && task.getStatus().equals(EnableStatusEnum.DISABLE.getValue())) {
bizManageJob.deleteJob(task);
return;
}
//截止时间为空则永久运行
if (task.getEndTime() != null) {
if (task.getEndTime().getTime() - System.currentTimeMillis() < 0) {
bizManageJob.deleteJob(task);
return;
}
}
//执行任务
syTaskService.runTask(RunTaskVO.builder().taskType(RunTaskTypeEnum.INCR)
.action(TaskActionEnum.AUTO)
.operator(TASK_USER).id(syTaskVO.getId()).build());
log.info("{} end at:{}", syTaskVO.getTaskName(), new Date());
} catch (Exception e) {
log.error("BaseBizJob run error ", e);
}
}
}
1.首先配置定时作业基类
/**
* @author ceshi
* @Title:
* @Package
* @Description: 表资产同步作业
* @date 2021/6/2316:28
*/
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
@Slf4j
public class TableSyncJob extends BaseBizJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
super.run(jobExecutionContext);
}
}
2.定时任务类
package com.sanyi.collect.config;
import com.sanyi.entity.SyTask;
import com.sanyi.collect.enums.EnableStatusEnum;
import com.sanyi.collect.service.SyTaskService;
import com.sanyi.collect.service.job.BeatJob;
import com.sanyi.collect.service.job.BizManageJob;
import com.sanyi.collect.service.job.ClusterBeatLogJob;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
/**
* @author ceshi
* @Title:
* @Package
* @Description: springboot 启动后执行方法
* @date 2021/6/2319:17
*/
@Component
@Order(value = 1)
public class ApplicationStartQuartzJob implements ApplicationRunner {
@Resource
SyTaskService syTaskService;
@Resource
BizManageJob bizManageJob;
private static final long BEAT_JOB_ID = 1L;
/**
* 每隔十分钟检查一次
*/
private static final String BEAT_CRON_EXPRESSION = "0 0/10 * * * ?";
/**
* 任务组名称
*/
private static final String TASK_GROUP = "SANY";
/**
* 异常任务状态检查名称
*/
private static final String TASK_NAME = "异常任务状态检查";
/**
* 1、查询数据库配置任务
* 2、循环添加任务到触发器
* 3、界面提供修改任务执行的cron表达式(停止任务可以修改其他参数)
* 4、启动和停止任务调用添加任务和移除任务方法
*
* @param args
* @return void
* @author sunwy
* @date 2021/7/10
*/
@Override
public void run(ApplicationArguments args) throws Exception {
if (syTaskService != null && bizManageJob != null) {
List<SyTask> taskList = syTaskService.findAll();
//添加作业
bizManageJob.addJob(SyTask.builder().className(BeatJob.class.getName())
.id(BEAT_JOB_ID)
.cronExpression(BEAT_CRON_EXPRESSION)
.startTime(new Date())
.endTime(null)
.taskName(TASK_NAME)
.status(EnableStatusEnum.ENABLE.getValue())
.taskGroup(TASK_GROUP).build());
//添加作业
bizManageJob.addJob(SyTask.builder().className(ClusterBeatLogJob.class.getName())
.id(-1L)
.cronExpression("0 */1 * * * ?")
.startTime(new Date())
.endTime(null)
.taskName("task-cluster-check")
.status(EnableStatusEnum.ENABLE.getValue())
.taskGroup(TASK_GROUP).build());
taskList.forEach(task -> bizManageJob.addJob(task));
}
}
}
3.启动后就加载的方法添加定时任务
/**
* 添加定时任务
*
* @param task
*/
@SuppressWarnings("unchecked")
public void addJob(SyTask task) {
log.info("新增定时任务:{}", task.getTaskName());
JobDetail jobDetail;
if (StringUtils.isEmpty(task.getClassName())) {
log.error("定时任务 {} className为空,无法启动", task.getTaskName());
return;
}
if (StringUtils.isEmpty(task.getCronExpression())) {
log.error("定时任务 {} CronExpression为空,无法启动", task.getTaskName());
return;
}
Class<?> aClass;
try {
aClass = Class.forName(task.getClassName());
} catch (ClassNotFoundException e) {
log.error("{} 未找到执行作业类,无法启动", task.getClassName());
return;
}
SyTaskVO taskVO = SyTaskVO.builder()
.className(task.getClassName())
.cronExpression(task.getCronExpression())
.endTime(task.getEndTime())
.id(task.getId())
.field(task.getIncrField())
.from(task.getIncrFrom())
.startTime(task.getStartTime())
.taskName(task.getTaskName())
.status(task.getStatus())
.taskGroup(task.getTaskGroup())
.build();
CronTrigger trigger = null;
// 调度容器设置JobDetail和Trigger
try {
//初始化触发器key
TriggerKey triggerKey = TriggerKey.triggerKey(String.valueOf(task.getId()), task.getTaskGroup());
//判断是否已经存在,存在则启动,不存在则创建新的触发器
boolean flag = scheduler.checkExists(triggerKey);
if (flag) {
//触发器已存在,则停止触发器
scheduler.pauseTrigger(triggerKey);
//卸载触发器
scheduler.unscheduleJob(triggerKey);
//移除作业
scheduler.deleteJob(JobKey.jobKey(String.valueOf(task.getId()), task.getTaskGroup()));
}
//传递参数
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put("taskId", taskVO);
String taskName = task.getId().toString();
//初始化作业信息
jobDetail = JobBuilder.newJob((Class<? extends Job>) aClass).withIdentity(taskName, task.getTaskGroup())
.usingJobData(jobDataMap).build();
// 触发器
TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
//现在开始
triggerBuilder.startNow();
// 创建Trigger对象
trigger = TriggerBuilder.newTrigger().withIdentity(String.valueOf(task.getId()), task.getTaskGroup()).withSchedule(CronScheduleBuilder.cronSchedule(task.getCronExpression())).build();
//加入调度器
scheduler.scheduleJob(jobDetail, trigger);
//开始调度
scheduler.start();
} catch (SchedulerException e) {
log.error("添加定时任务失败", e);
}
log.info("新增定时任务结束:{}", task.getTaskName());
}
4.添加定时任务到 Scheduler调度器中
package com.sanyi.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.FieldStrategy;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.ibatis.type.JdbcType;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 任务属性表
* </p>
*
* @author sunwy
* @since 2021-06-21
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Builder
public class SyTask implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId
@JsonFormat(shape = JsonFormat.Shape.STRING)
private Long id;
/**
* 任务名称
*/
private String taskName;
/**
* 任务组
*/
private String taskGroup;
/**
* cron表达式
*/
private String cronExpression;
/**
* 增量字段
*/
private String incrField;
/**
* 增量字段开始
*/
private Date incrFrom;
/**
* 启动作业时间
*/
private Date startTime;
/**
* 作业截止时间
*/
@TableField(value = "end_time", updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.DATE)
private Date endTime;
/**
* 更新时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
/**
* 创建人
*/
private String createBy;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/**
* 修改人
*/
private String updateBy;
private Integer status;
private String className;
/**
* 是否展示
*/
private Integer isShow;
/**
* 是否显示增量执行按钮
*/
@TableField("is_show_incr")
private Integer isShowIncr;
/**
* 是否显示全量执行按钮
*/
@TableField("is_show_all")
private Integer isShowAll;
}
4.1 存储在数据库的定时任务配置信息bean类
@Override
public void runTask(RunTaskVO taskVO) {
log.info("dmap task run {}", taskVO.getId());
SyTaskQueue syTaskQueue = addTaskQueue(taskVO);
try {
syTaskQueueService.add(syTaskQueue);
//api作业
runApiJob(taskVO, syTaskQueue);
//表资产采集作业
runTableJob(taskVO, syTaskQueue);
//报表采集作业
//runReportJob(taskVO, syTaskQueue);
//血缘关系作业
runCapitalRelationshipJob(taskVO, syTaskQueue);
//api目录作业
runApiCategoryJob(taskVO, syTaskQueue);
//资产热度作业
runCapitalOperationHeatJob(syTaskQueue);
//api到kafka作业
runApiToKafkaJob(taskVO, syTaskQueue);
//数据产品到kafka作业
//runDataToKafkaJob(taskVO, syTaskQueue);
//新指标血缘同步任务作业
runIndicatorToKafkaJob(taskVO, syTaskQueue);
//新指标到kafka作业
runSyMetricsToKafkaJob(taskVO, syTaskQueue);
//数据表到kafka作业
runTableToKafkaJob(taskVO, syTaskQueue);
//报表到kafka作业
//runReportToKafkaJob(taskVO, syTaskQueue);
//资产脱敏规则采集作业
runSensitiveDataJob(taskVO, syTaskQueue);
//指标落地表字段更新作业
runIndicatorFieldUpdateJob(taskVO, syTaskQueue);
//老指标同步kafka
runIndicatorSourceUpdateJob(syTaskQueue);
//指标落地表详细信息作业
runIndicatorFieldInfoUpdateJob(syTaskQueue);
//资产pv定时清理作业
runCapitalDeletedHistoryPVJob(syTaskQueue);
//hbase同步码表作业
runHbaseToSyMapJob(taskVO, syTaskQueue);
//更新任务完成状态 完成时间
syTaskQueue.setTaskStatus(TaskQueueStatusEnum.FINISHED.getValue());
syTaskQueue.setTaskEnd(new Date());
syTaskQueueService.updateById(syTaskQueue);
} catch (Exception e) {
log.info("runTask ", e);
syTaskQueue.setTaskStatus(TaskQueueStatusEnum.FAILURE.getValue());
syTaskQueue.setTaskEnd(new Date());
syTaskQueue.setReason(e.getMessage());
syTaskQueueService.updateById(syTaskQueue);
}
}
5.根据定时id执行特定定时任务
/**
* @author ceshi
* @Title:
* @Package
* @Description: 表资产同步作业
* @date 2021/6/2316:28
*/
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
@Slf4j
public class TableSyncJob extends BaseBizJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
super.run(jobExecutionContext);
}
}
6.执行某一个定时任务
本文介绍了一个基于SpringBoot实现的定时任务系统,包括任务配置、任务执行和任务管理等核心功能。通过具体代码示例展示了如何创建和管理定时任务。
853

被折叠的 条评论
为什么被折叠?



