自定义注解为xxlJob定时任务添加监控
监控
自定义一个注解,要求实现以下功能:
-
监控xxlJob任务执行是否有异常,有异常将异常信息 监控
-
监控xxlJob任务执行的时长,如果超过3个小时 监控
-
监控xxlJob任务是否执行成功,如果不成功 监控
首先,定义自定义注解:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义注解,用于监控XXLJob任务
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MonitorXxlJob {
/**
* 是否开启异常日志记录,默认开启
*/
boolean logException() default true;
/**
* 是否开启超时日志记录,默认开启
*/
boolean logTimeout() default true;
/**
* 超时时长(小时),默认3小时
*/
int timeoutHours() default 3;
}
接下来,创建一个AOP切面类来处理注解的行为:
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.concurrent.TimeUnit;
/**
* 监控XXLJob任务的切面类
*/
@Aspect
@Component
public class XxlJobMonitorAspect {
@Around("@annotation(monitor)")
public Object monitorTask(ProceedingJoinPoint joinPoint, MonitorXxlJob monitor) throws Throwable {
long startTime = System.currentTimeMillis();
try {
Object result = joinPoint.proceed();
System.out.println("任务[" + joinPoint.getSignature().getName() + "]执行成功");
return result;
} catch (Exception e) {
if (monitor.logException()) {
System.err.println("任务[" + joinPoint.getSignature().getName() + "]执行异常: " + e.getMessage());
}
throw e;
} finally {
long elapsedTime = System.currentTimeMillis() - startTime;
long timeout = TimeUnit.HOURS.toMillis(monitor.timeoutHours());
if (monitor.logTimeout() && elapsedTime > timeout) {
System.err.println("任务[" + joinPoint.getSignature().getName() + "]执行超时: " +
String.format("%dh %dm %ds", (elapsedTime / (1000 * 60 * 60)),
(elapsedTime / (1000 * 60)) % 60, (elapsedTime / 1000) % 60));
}
}
}
}
测试
import org.springframework.stereotype.Component;
import com.example.xxljobmonitor.annotation.MonitorXxlJob;
@Component
public class XxlJobExecutor {
/**
* 示例任务1,可能会抛出异常
*/
@MonitorXxlJob(logException = false) // 不记录异常日志
public void task1() {
try {
// 任务逻辑...
Thread.sleep(5000); // 模拟5秒执行时间
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Task1执行中断", e);
}
}
/**
* 示例任务2,正常执行,但超时
*/
@MonitorXxlJob(timeoutHours = 1) // 设置1小时超时
public void task2() {
try {
// 任务逻辑...
Thread.sleep(360_000); // 模拟1小时执行时间
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Task2执行中断", e);
}
}
/**
* 示例任务3,正常执行,不会超时
*/
@MonitorXxlJob
public void task3() {
// 任务逻辑...
Thread.sleep(10_000); // 模拟10秒执行时间
}
}
利用切面来完成xxlJob中是否出现异常和耗时的监控