我们有很多定时任务在任务工程中执行,但是如果我们不加以监控,很有可能定时任务死掉或者卡住我们都不知道。

所以需要做一个任务监控。监控任务当前执行的状态。

还是那样,先让定时任务启动起来,当前我们使用的是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="当日到期的还款人发短信")
/**
* * <p>
* 定时任务监控,用于方法上<br/>
* 在新建定时任务时,在方法上写taskNo=任务编号,此时拦截器会根据编号信息,获取任务执行情况,更改任务情况,并且给任务加上异常捕获,
* 监控任务信息。
* </p>
* @author chenweixian 陈惟鲜
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTask { 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、完成。。

springAop Schedule,注解annotation 实现任务监控的更多相关文章

  1. springAop,注解annotation + redis 实现分布式锁

    当前流行的系统,就是分布式系统.所谓分布式,我个人理解,是很多的服务分布在不同的机器上,都是相同功能模块.但是容易出现一个问题,就是并发时的问题. 我们传统的锁,只能锁住一个服务器上的方法,让其在一个 ...

  2. Java的注解(Annotation)

    1.什么是注解 Annotation is code about the code, that is metadata about the program itself. Java注解,是Java5. ...

  3. Java Android 注解(Annotation) 及几个常用开源项目注解原理简析

    不少开源库(ButterKnife.Retrofit.ActiveAndroid等等)都用到了注解的方式来简化代码提高开发效率. 本文简单介绍下 Annotation 示例.概念及作用.分类.自定义. ...

  4. Java注解Annotation学习

    学习注解Annotation的原理,这篇讲的不错:http://blog.csdn.net/lylwo317/article/details/52163304 先自定义一个运行时注解 @Target( ...

  5. Java中注解Annotation的定义、使用、解析

    此例子,用于说明如何在Java中对“注解 Annotation”的定义.使用和解析的操作.注解一般用于自定义开发框架中,至于为什么使用,此处不作过多说明,这里只说明如何使用,以作备记.下面例子已测试, ...

  6. java基础-注解Annotation原理和用法

    在很多java代码中都可以看到诸如@Override.@Deprecated.@SuppressWarnings这样的字符,这些就是注解Annotation.注解最早在jdk5中被引入,现在已经成为j ...

  7. Enum枚举类|注解Annotation

    Enum枚举类 ①枚举类和普通类的差别: 使用 enum 定义的枚举类默认继承了 java.lang.Enum 类 枚举类的构造器仅仅能使用 private 訪问控制符 枚举类的全部实例必须在枚举类中 ...

  8. JUnit扩展:引入新注解Annotation

    发现问题 JUnit提供了Test Suite来帮助我们组织case,还提供了Category来帮助我们来给建立大的Test Set,比如BAT,MAT, Full Testing. 那么什么情况下, ...

  9. Java - 注解 (Annotation)

    Java - 注解 (Annotation)   一.基本的 Annotation     > 使用 Annotation 时要在其前面增加 @符号,并把该 Annotation 当成一个修饰符 ...

随机推荐

  1. 十二、使用PWM调整LCD背光亮度

    和手机一样,开发板中也带有调整背光亮度的功能. 调整背光亮度依赖于PWM,它通过调节脉冲宽度来控制背光亮度,此方式需要使用PWM驱动.本章将对其进行讲解. 一.用户空间调整背光亮度 一般应用程序可以通 ...

  2. spring cloud微服务实践七

    在spring cloud 2.x以后,由于zuul一直停滞在1.x版本,所以spring官方就自己开发了一个项目 Spring Cloud Gateway.作为spring cloud微服务的网关组 ...

  3. SAS学习笔记27 卡方检验

    卡方检验(chi-square test)是英国统计学家Pearson提出的一种主要用于分析分类变量数据的假设检验方法,该方法主要目的是推断两个或多个总体率或构成比之间有无差别. 卡方分布界值表的依据 ...

  4. QCache<key,T> 就定义了一个缓存,其类似于map,好处是QCache自动获得被插入对象的所有权,控制所有对象的costs总和(自动管理对象的生存时间。正经数据是不会用到它的,辅助控制才有可能用到它)

    在软件开发中,我们经常需要在内存中存储一些临时数据用于后续相关计算.我们一般把这些数据存储到某个数组里,或者STL中的某个合适的容器中.其实,在Qt中直接为我们提供了一个QCache类专用于这种需求. ...

  5. Kafka 消息中间件

    kafka简介与应用场景 Apache Kafka是分布式发布-订阅消息系统,在 kafka官网上对 kafka 的定义:一个分布式发布-订阅消息传递系统. 它最初由LinkedIn公司开发,Link ...

  6. Spring Boot 全局Exception处理

    一.代码如下 package com.zxguan; import org.springframework.web.bind.annotation.ControllerAdvice; import o ...

  7. MongoDB知识小结

    一.术语 RDBMS MongoDB 数据库 数据库 表格 集合 行 文档 列 字段 表联合 嵌套文档 主键 主键 (MongoDB 提供了 key 为 _id ) 数据库 数据库名可以是满足以下条件 ...

  8. [JZOJ5279]香港记者题解--最短路图

    [JZOJ5279]香港记者题解--最短路图 题目链接 过 于 暴 力 分析 有一个naiive的想法就是从1到n跑最短路,中途建图,然后在图上按字典序最小走一遍,然而·这是不行的,你这样跳不一定能跳 ...

  9. win中使用curl上传文件报错

    今天晚上复现“WordPress插件Easy WP SMTP反序列化漏洞”时,需要使用curl上传文件,我又用的windows环境,一直出错 curl: (26) couldn't open file ...

  10. linux命令安装docker

    安装: 1.Docker要求CentOS系统的内核版本高于 3.10 ,通过 uname -r 命令查看你当前的内核版本是否支持安账docker 2.更新yum包:sudo yum update 3. ...