Spring-boot-admin: Scheduled task with cron not working as expected

Created on 27 Jun 2017  路  6Comments  路  Source: codecentric/spring-boot-admin

Hello. I have a simple Spring Boot application in which I just included the spring-boot-admin-starter-client (version 1.5.2). Everything works fine except for the scheduled method detailed below:

@Service
public class SomeService {

    @Scheduled(cron = "${cron.task.say.hello}")
    public void someMethod() {
        System.out.println("Hello world!");
    }

}

Being cron.task.say.hello: "* * * * * MON-FRI" in the application.yml file.

As you probably noticed it should print _Hello world!_ every second but it doesn't work. It prints the message every different periods of time. Sometimes it takes 30 seconds, sometimes 20, it varies.

The application麓s entry point is below:

@EnableAsync
@EnableScheduling
@SpringBootApplication
public class SchedulerStarter {

    public static void main(String[] args) throws IOException {
        SpringApplication.run(SchedulerStarter.class, args);
    }

}

Removing spring-boot-admin-starter-client and then using spring-boot-starter works as expected.

Not sure if this is a bug or maybe I'm missing a piece of the puzzle.

client wontfix

Most helpful comment

So basically it's always a good idea to configure a TaskScheduler when using @EnableSchduling...
Your TaskScheduler is picked up because of the name...

From the Spring code:

More than one TaskScheduler bean exists within the context, and none is named 'taskScheduler'. Mark one of them as primary or name it 'taskScheduler' (possibly as an alias); or implement the SchedulingConfigurer interface and call ScheduledTaskRegistrar#setScheduler explicitly within the configureTasks() callback

Since the scheduler provided by the SBA client is very similiar to the default one from @EnableScheduling and doesn't interfere when you are providing a custom one, I tend to not fix this issue.

All 6 comments

Could you try printing the thread name additional to your "Hello world!"? I the name is prefixed with registrationTask your scheduled method picks up the registrationTaskScheduler from SBA client...

Exactly.

Output using SBA client:

Thread.currentThread().getName(): registrationTask1
Thread.currentThread().getId(): 111
Thread.currentThread().getPriority(): 5
Thread.currentThread().getThreadGroup(): java.lang.ThreadGroup[name=main,maxpri=10]
Thread.currentThread().getState(): RUNNABLE
Thread.currentThread().isDaemon(): false

Output using SB:

Thread.currentThread().getName(): pool-2-thread-1
Thread.currentThread().getId(): 106
Thread.currentThread().getPriority(): 5
Thread.currentThread().getThreadGroup(): java.lang.ThreadGroup[name=main,maxpri=10]
Thread.currentThread().getState(): RUNNABLE
Thread.currentThread().isDaemon(): false

I'm looking for a way to specify which scheduler should Spring use to run my task.

Thread dump if helps.

"registrationTask1" #111 prio=5 os_prio=31 tid=0x00007fb20244f000 nid=0xfd03 runnable [0x00007000143e1000]
   java.lang.Thread.State: RUNNABLE
    at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
    at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:928)
    at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1323)
    at java.net.InetAddress.getLocalHost(InetAddress.java:1500)
    - locked <0x00000006c00784b0> (a java.lang.Object)
    at de.codecentric.boot.admin.client.registration.DefaultApplicationFactory.getLocalHost(DefaultApplicationFactory.java:119)
    at de.codecentric.boot.admin.client.registration.DefaultApplicationFactory.getServiceHost(DefaultApplicationFactory.java:104)
    at de.codecentric.boot.admin.client.registration.DefaultApplicationFactory.getServiceUrl(DefaultApplicationFactory.java:65)
    at de.codecentric.boot.admin.client.registration.DefaultApplicationFactory.getManagementUrl(DefaultApplicationFactory.java:77)
    at de.codecentric.boot.admin.client.registration.DefaultApplicationFactory.createApplication(DefaultApplicationFactory.java:46)
    at de.codecentric.boot.admin.client.registration.ApplicationRegistrator.createApplication(ApplicationRegistrator.java:126)
    at de.codecentric.boot.admin.client.registration.ApplicationRegistrator.register(ApplicationRegistrator.java:65)
    at de.codecentric.boot.admin.client.registration.RegistrationApplicationListener$1.run(RegistrationApplicationListener.java:80)
    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(FutureTask.java:308)
    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:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:748)

Ok. I fix it according to this: https://stackoverflow.com/a/34646639/2811722.

Just adding the Spring thread pool task scheduler bean manually with a bigger pool size fixes it.

    @Bean
    public ThreadPoolTaskScheduler taskScheduler(){
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(20);
        return  taskScheduler;
    }

So basically it's always a good idea to configure a TaskScheduler when using @EnableSchduling...
Your TaskScheduler is picked up because of the name...

From the Spring code:

More than one TaskScheduler bean exists within the context, and none is named 'taskScheduler'. Mark one of them as primary or name it 'taskScheduler' (possibly as an alias); or implement the SchedulingConfigurer interface and call ScheduledTaskRegistrar#setScheduler explicitly within the configureTasks() callback

Since the scheduler provided by the SBA client is very similiar to the default one from @EnableScheduling and doesn't interfere when you are providing a custom one, I tend to not fix this issue.

I agree. This wasn't an issue of SBA client just lack of knowledge of Spring Scheduling from my side.

Thanks for the feedback!

Was this page helpful?
0 / 5 - 0 ratings