我们有很多定时任务在任务工程中执行,但是如果我们不加以监控,很有可能定时任务死掉或者卡住我们都不知道。
所以需要做一个任务监控。监控任务当前执行的状态。
还是那样,先让定时任务启动起来,当前我们使用的是spring提供的schedule执行定时任务。注意,这个默认情况下是单线执行,就是说你有很多定时任务,你的时间执行很频繁,他只会给你排队执行,不会到时间立马执行。如果想要配置多个定时任务同时执行,那么只需要在你任务标签上加上@Async。一般情况下。不是忒紧急的,不需要加。加上后,你就需要给你的方法调用的数据做好异步同步控制了。具体调用,可参考前一篇文章。
ok,废话不多说,开始弄代码。
1、spring配置加上以下配置,实现任务调度与切面生效。
<!-- 切面开关 -->
<aop:aspectj-autoproxy />
<!-- 定时器开关 -->
<task:annotation-driven />
2、任务信息实现:
/\*\*
\* 提醒当天到期还款的还款人发短信
\*/
@MyTask(taskNo="smsNotifyRepaymenterToday", taskDesc="当日到期的还款人发短信")
@Scheduled(cron = "${SmsTaskExecutor.smsNotifyRepaymenterToday}")
public void smsNotifyRepaymenterToday() {
String message = StatusContants.TASK\_INFO\_SMS\_NOTIFY\_REPAYMENTER\_TODAY.getName();
String taskNo = StatusContants.TASK\_INFO\_SMS\_NOTIFY\_REPAYMENTER\_TODAY.getIndex();
if (!taskService.taskDo(taskNo)){return ;}
try{
taskService.taskUpdate(taskNo, StatusContants.SYSTEM\_TABLE\_STATUS\_1.getIndex());
logger.info(message + ControllerContants.MESSAGE\_START);
// 计算发送时间范围
String notifyDateStr = dictionaryVoService.findDeductDate(); // 会计日期当天
String deductDateStart = notifyDateStr;
String deductDateEnd = notifyDateStr;
// 发送
phoneMsgService.notifyRepaymenterTodayBySms(deductDateStart, deductDateEnd);
logger.info(message + ControllerContants.MESSAGE\_END);
}catch (Exception e) {
logger.error(message+"异常", e);
exceptionInfoService.insert(message+"异常", StatusContants.LOG\_TYPE\_EXCPETION.getIndex(), MyStringUtils.getExceptionDetail(e), getClass().getName()+".smsNotifyRepaymenter");
}finally{
taskService.taskUpdate(taskNo, StatusContants.SYSTEM\_TABLE\_STATUS\_0.getIndex());
}
}
3、注解标签实现:
@MyTask(taskNo="smsNotifyRepaymenterToday", taskDesc="当日到期的还款人发短信")
/**
* *
* 定时任务监控,用于方法上
* 在新建定时任务时,在方法上写taskNo=任务编号,此时拦截器会根据编号信息,获取任务执行情况,更改任务情况,并且给任务加上异常捕获,
* 监控任务信息。
*
String taskNo();
String taskDesc();
}
4、监控切面的实现。
package com.chenweixian.task.aop;
import java.math.BigDecimal;
import java.util.Date;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import com.opensymphony.oscache.util.StringUtil;
/**Spring的定时任务推送监控
*
* @author chenweixian
*
*/
@Aspect
@Order(1) // 排序
@Component
public class ScheduleMonitoringInterceptor {
private Logger logger = Logger.getLogger(getClass());
@Autowired
private ActiveMqUtil activeMqUtil;
@Async
@Pointcut("@annotation(org.springframework.scheduling.annotation.Scheduled)") // 用于拦截标签
private void anyMethod(){}//定义一个切入点
/\*\*
\*
\* @Title:doAround
\* @Description: 环绕触发
\* @author 陈惟鲜
\* @date 2014年11月3日 下午1:58:45
\* @param point
\* @return
\* @throws Throwable
\*/
@Around("anyMethod() && @annotation(myTask)")
public Object doAround(ProceedingJoinPoint point, MyTask myTask) throws Throwable {
Date startTime = MyDateUtil.getCurrentDateTime();// 开始时间
// 执行完方法的返回值:调用proceed()方法,就会触发切入点方法执行
Object result = point.proceed();// result的值就是被拦截方法的返回值
Date endTime = MyDateUtil.getCurrentDateTime();// 结束时间
try{
this.writeLog(point, myTask, startTime, endTime);
}catch(Exception e){
logger.info("记录监控日志异常。。");
}
return result;
}
/\*\*\*记录日志\*/
private void writeLog(JoinPoint point, MyTask myTask, Date startTime, Date endTime){
String taskdesc = StatusContants.getName(StatusTypeContants.TYPE\_ID\_TASK\_INFO, myTask.taskNo());
if (StringUtil.isEmpty(taskdesc)){
taskdesc = "";
}
ProcedureMonitor procedureMonitor = new ProcedureMonitor();
procedureMonitor.setAutoId(UUIDUtils.generateUUID64());
procedureMonitor.setIpAddress(MyStringUtils.getIpString());// 机器IP
procedureMonitor.setStartTime(startTime);// 开始执行时间
procedureMonitor.setEndTime(endTime);// 结束执行时间
procedureMonitor.setConsumeTimes(new BigDecimal(endTime.getTime()-startTime.getTime()));// 总耗时时间
procedureMonitor.setExceptionFlag(StatusContants.SYSTEM\_TABLE\_STATUS\_0.getIndex());// 是否异常
procedureMonitor.setTaskNo(myTask.taskNo()); // 任务编号
procedureMonitor.setTaskName(myTask.taskDesc()); // 任务编号对应名称
procedureMonitor.setRemark("【"+point.getSignature().getDeclaringTypeName()+"."+point.getSignature().getName()+"】"+taskdesc); // 所在的类.方法
procedureMonitor.setBusinessType(StatusContants.PROCEDURE\_MONITOR\_TASK.getIndex()); // 监控类型
// 发送mq消息
activeMqUtil.sendMq(ActivityMqContants.TASK\_PROCEDURE\_MONITOR, JSONObject.fromObject(procedureMonitor).toString());
}
}
5、完成。。
手机扫一扫
移动阅读更方便
你可能感兴趣的文章