AOP 实现(定时器)方法监控——Monitor

2 篇文章 0 订阅

AOP 实现(定时器)方法监控——Monitor

描述

背景

  1. 定时任务出现问题,在修复发布前,需要临时停下来,可之前又没有埋点;
  2. 定时任务需要临时手动触发一下,可之前又没有埋点;

Monitor 就是用来解决上面这些问题的。

@MonitorMethod 标记的方法,并且方法所在的类被 @MonitorClass 标记,那么这个方法就可监控。

针对可监控的方法可以做下面这些事情:

  1. 可以查看所有被监控方法的状态;(/monitor/list)
  2. 可以对监控的方法启用或禁用;(/monitor/put?key=com.lyloou.demo&value=OFF
  3. 可以手动触发被监控的方法;(/monitor/call?key=com.lyloou.demo.ScheduleService.runPer10s

使用场景

  • 临时禁用定时器的运行;
  • 临时禁用某个方法的运行;
  • 临时手动调用定时方法;

原理:

  1. 先将需要监控的方法,通过注解+反射加入到一个 map 中,;
  2. 针对可能会监控的方法,通过注解标记(AOP 面向切面编程),所有对此方法的调用都会进入到@Around标记的环绕方法中;
  3. 可以在@Around方法中拦截处理,判断方法的可用状态,是否需要向下进行;

使用:

配置

配置方式 1:

monitor:
  default-status: "ON"
  scan-package: com.lyloou.demo

配置方式 2:

@Configuration
public class MonitorConfiguration {
    @Bean
    public MonitorConfig monitorStatusConfig() {
        final MonitorConfig config = new MonitorConfig();
        config.setDefaultStatus(MonitorStatus.ON.name());
        // 多个包名,用逗号隔开
        config.setScanPackages(Joiner.on(",").join("com.lyloou.demo", "com.lyloou.another.demo"));
        return config;
    }
}

代码

@EnableScheduling
@Service
@Slf4j
// 1. 在需要干预的类上加上 @MonitorClass
@MonitorClass
public class ScheduleService {
    // 2. 在需要干预的方法上加上 @MonitorMethod
    @MonitorMethod
    @Scheduled(cron = "0/10 * * * * *")
    public void runPer10s() {
        // 当被标记有@MonitorMethod的方法被调用时,会进入 MonitorAspect 中,判断方法的MonitorStatus是否为ON,如果是(默认是ON,可以通过api修改),才会向下进行
        log.info("runPer10s...");
    }
}

也可以在 @MonitorClass 和 @MonitorMethod 注解参数中加入自定义的名字做为 key。
默认的 key 为:包名.类名.方法名

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R0v1rxbo-1614927691142)(http://cdn.lyloou.com/img/Readme-2021-03-05-14-51-28.png)]

api:

# 列出被监控的方法
http://localhost:8080/monitor/list

# 获取某个具体的方法
http://localhost:8080/monitor/get?key=com.lyloou.monitor.ScheduleService.runPer10s

# 修改某个具体的方法
http://localhost:8080/monitor/put?key=com.lyloou.monitor.ScheduleService.runPer10s&value=OFF

# 修改所有被监听的方法
http://localhost:8080/monitor/putAll?value=OFF

# 手动调用被监听的方法
http://localhost:8080/monitor/call?key=com.lyloou.monitor.ScheduleService.runPer10s

具体逻辑查看 MonitorController

源码

https://github.com/lyloou/spring-monitor-parent

扩展

  • 也可以将 @Scheduled 做为一个切入点;
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Spring AOP是Spring框架中的一个重要模块,它提供了面向切面编程(AOP)的支持。AOP是一种编程思想,它可以在不改变原有代码的情况下,通过在程序运行时动态地将代码“织入”到现有代码中,从而实现对原有代码的增强。 Spring AOP提供了基于注解的AOP实现,使得开发者可以通过注解的方式来定义切面、切点和通知等相关内容,从而简化了AOP的使用。 下面是一个基于注解的AOP实现的例子: 1. 定义切面类 ```java @Aspect @Component public class LogAspect { @Pointcut("@annotation(Log)") public void logPointcut() {} @Before("logPointcut()") public void beforeLog(JoinPoint joinPoint) { // 前置通知 System.out.println("执行方法:" + joinPoint.getSignature().getName()); } @AfterReturning("logPointcut()") public void afterLog(JoinPoint joinPoint) { // 后置通知 System.out.println("方法执行完成:" + joinPoint.getSignature().getName()); } @AfterThrowing(pointcut = "logPointcut()", throwing = "ex") public void afterThrowingLog(JoinPoint joinPoint, Exception ex) { // 异常通知 System.out.println("方法执行异常:" + joinPoint.getSignature().getName() + ",异常信息:" + ex.getMessage()); } } ``` 2. 定义业务逻辑类 ```java @Service public class UserService { @Log public void addUser(User user) { // 添加用户 System.out.println("添加用户:" + user.getName()); } @Log public void deleteUser(String userId) { // 删除用户 System.out.println("删除用户:" + userId); throw new RuntimeException("删除用户异常"); } } ``` 3. 在配置文件中开启AOP ```xml <aop:aspectj-autoproxy/> <context:component-scan base-package="com.example"/> ``` 在这个例子中,我们定义了一个切面类LogAspect,其中通过@Aspect注解定义了一个切面,通过@Pointcut注解定义了一个切点,通过@Before、@AfterReturning和@AfterThrowing注解分别定义了前置通知、后置通知和异常通知。 在业务逻辑类中,我们通过@Log注解标注了需要增强的方法。 最后,在配置文件中,我们通过<aop:aspectj-autoproxy/>开启了AOP功能,并通过<context:component-scan>扫描了指定包下的所有组件。 这样,当我们调用UserService中的方法时,就会触发LogAspect中定义的通知,从而实现对原有代码的增强。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值