spring boot 定時任務在啓動時執行幾次 就不執行了

定時任務執行幾次就不執行了

背景

今天debug項目時發現所有定時任務在程序啓動時執行幾次後就不執行了
檢查代碼也沒發現有什麼問題 通過jstack查看線程信息時 發現只有一個名字爲scheduling-1的線程 而且還是time-waiting狀態的 分析調用鏈發現是手動調用了Thread.sleap方法導致
原因: 項目中有多個定時任務要運行 而只有一個核心線程 還是阻塞的 所以其他定時任務得不到執行

分析方案

jstack 25097|grep scheduling -A 10

查看結果請點擊附錄1

解決方案

爲定時任務配置線程池 讓它支持多線程
asyncTaskExecutor 針對@Async方法
taskScheduler 針對@Scheduled方法

public class TaskConfig {
    public TaskConfig() {
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnAnnotation(EnableAsync.class)
    public AsyncTaskExecutor asyncTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(12);
        executor.setQueueCapacity(20);
        executor.setMaxPoolSize(50);
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("async-");
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAwaitTerminationSeconds(60);
        executor.setRejectedExecutionHandler(RejectedExecutionHandlers.discardPolicy());
        return executor;
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnAnnotation(EnableScheduling.class)
    public ThreadPoolTaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(8);
        scheduler.setThreadNamePrefix("task-");
        scheduler.setWaitForTasksToCompleteOnShutdown(true);
        scheduler.setAwaitTerminationSeconds(60);
        return scheduler;
    }
}
@Import({TaskConfig.class})
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EnableTaskMultiThreading {
}

@EnableTaskMultiThreading 開啓任務多線程支持

@SpringBootApplication
@EnableScheduling
@EnableTaskMultiThreading
public class Application {
	public static void main(String[] args) {
		SpringApplication.run(XynetServiceStatisticsApplication.class, args);
	}
}

附錄1

nailsoul@nailsoul-company-pc:~$ jstack 25097|grep scheduling -A 10
"scheduling-1" #81 prio=5 os_prio=0 tid=0x00007fd556891000 nid=0x629a waiting on condition [0x00007fd52d69f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
	at java.lang.Thread.sleep(Native Method)
	at com.xynet.cloud.core.util.ThreadUtil.sleep(ThreadUtil.java:6)
	at com.xynet.statistics.service.impl.StatisticsLeakyScreenScanningServiceImpl.scannerStatisticsLeakyScreenDatasByType(StatisticsLeakyScreenScanningServiceImpl.java:184)
	at com.xynet.statistics.service.impl.StatisticsLeakyScreenScanningServiceImpl.scannerStatisticsLeakyScreenTaskByCrontab(StatisticsLeakyScreenScanningServiceImpl.java:123)
	at com.xynet.statistics.service.impl.StatisticsLeakyScreenScanningServiceImpl.scannerStatisticsLeakyScreenDatas(StatisticsLeakyScreenScanningServiceImpl.java:79)
	at com.xynet.statistics.config.StatisticsSchedule.startRecordLeakyScreenScanner(StatisticsSchedule.java:123)
	at com.xynet.statistics.config.StatisticsSchedule$$FastClassBySpringCGLIB$$e54fcc5a.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:769)
--
	at org.springframework.cloud.sleuth.instrument.scheduling.TraceSchedulingAspect.traceBackgroundThread(TraceSchedulingAspect.java:73)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633)
	at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
--
	at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84)
	at org.springframework.cloud.sleuth.instrument.async.TraceRunnable.run(TraceRunnable.java:67)
	at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.runAndReset$$$capture(FutureTask.java:308)
	at java.util.concurrent.FutureTask.runAndReset(FutureTask.java)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
	
nailsoul@nailsoul-company-pc:~$ 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章