美文网首页
扩展Spring Scheduler的执行逻辑

扩展Spring Scheduler的执行逻辑

作者: 十毛tenmao | 来源:发表于2021-06-18 22:52 被阅读0次

    Spring Scheduler因为是单线程执行,所以容易出现部分任务耗时太长,虽然可以使用多线程的方式来提升效率,但是也担心定时任务占用太多的资源,所以还是尽可能地优化定时任务的耗时,那我们首先就可以对耗时进行监控

    Spring Scheduler使用ScheduledAnnotationBeanPostProcessor#createRunnable来创建定时任务的执行Runnable(实际类型是ScheduledMethodRunnable),那么我们就可以对该ScheduledMethodRunnable进行扩展,增加任务耗时,设置traceId,方便进行日志分析等

    扩展ScheduledMethodRunnable

    • 设置traceId
    • 监控耗时
    @Slf4j
    public class TenmaoScheduledMethodRunnable extends ScheduledMethodRunnable {
        public TenmaoScheduledMethodRunnable(Object target, Method method) {
            super(target, method);
        }
    
        public TenmaoScheduledMethodRunnable(Object target, String methodName) throws NoSuchMethodException {
            super(target, methodName);
        }
    
        @Override
        public void run() {
            //设置traceId,方便进行日志跟踪
            MDC.put("traceId", UUID.randomUUID().toString().replaceAll("-", ""));
            log.info("{}: start to run", getMethod());
            long startMillis = System.currentTimeMillis();
            try {
                super.run();
            } finally {
                //监控耗时
                long endMillis = System.currentTimeMillis();
                log.info("{}: cost {} millis", getMethod(), endMillis - startMillis);
                MDC.remove("traceId");
            }
        }
    }
    

    扩展ScheduledAnnotationBeanPostProcessor

    让ScheduledAnnotationBeanPostProcessor使用TenmaoScheduledMethodRunnable作为定时任务真正的执行逻辑

    @Component
    public class TenmaoScheduledAnnotationBeanPostProcessor extends ScheduledAnnotationBeanPostProcessor {
        @Override
        protected Runnable createRunnable(Object target, Method method) {
            //这两行代码从ScheduledAnnotationBeanPostProcessor#createRunnable复制过来
            Assert.isTrue(method.getParameterCount() == 0, "Only no-arg methods may be annotated with @Scheduled");
            Method invocableMethod = AopUtils.selectInvocableMethod(method, target.getClass());
            
            //把ScheduledMethodRunnable替换为TenmaoScheduledMethodRunnable
            return new TenmaoScheduledMethodRunnable(target, invocableMethod);
        }
    }
    

    注意

    • 如果没有在TenmaoScheduledAnnotationBeanPostProcessor增加@Component注解,那么@EnableScheduling一定要去掉

    思考

    • 是不是也可以使用Aop的方式实现这一点呢? 貌似有一点麻烦,因为很多定时任务是private,并不会被代理

    参考

    相关文章

      网友评论

          本文标题:扩展Spring Scheduler的执行逻辑

          本文链接:https://www.haomeiwen.com/subject/orolyltx.html