Spring任务:调度程序XML配置问题



我在Bean中有一些函数,我想每5秒运行一次,变量应该是"广义"的,而不是硬编码的:

工作代码如下所示:(我已经用相关的XML编写)

@Component
@EnableScheduling
public class CacheManager{

@Scheduled(initialDelay=0,fixedDelay=5000)  
public void updateConfigurations() {
Some Code Here
}
@Scheduled(initialDelay=0,fixedDelay=5000)
public void updateMapping() {
Some Code Here
}
}

这两个函数每5秒钟执行一次。

现在,当我想把它移到XML:中时

<task:scheduler id="ttScheduler" pool-size="1" />
<task:scheduled-tasks scheduler="ttScheduler">
<task:scheduled ref="cacheManager" method="updateConfigurations" fixed-delay="5000" initial-delay="0" />
<task:scheduled ref="cacheManager" method="updateMapping" fixed-delay="5000" initial-delay="0" />
</task:scheduled-tasks>

@Component
public class CacheManager{

public void updateConfigurations() {
log.info("update configurations");
Some Code
log.info("end update configurations");
}
public void updateMapping() {
Some Code Here
}
}

这两个函数都可以毫不延迟地执行。输出:

20190127-17:24:48.254  INFO [ttScheduler-1] CacheManager[109] - end update  configurations
20190127-17:24:48.255  INFO [ttScheduler-1] CacheManager[105] - update  configurations
20190127-17:24:48.282  INFO [ttScheduler-1] CacheManager[109] - end update  configurations
20190127-17:24:48.283  INFO [ttScheduler-1] CacheManager[105] - update  configurations
20190127-17:24:48.311  INFO [ttScheduler-1] CacheManager[109] - end update  configurations
20190127-17:24:48.312  INFO [ttScheduler-1] CacheManager[105] - update  configurations
20190127-17:24:48.337  INFO [ttScheduler-1] CacheManager[109] - end update  configurations
20190127-17:24:48.337  INFO [ttScheduler-1] CacheManager[105] - update  configurations
20190127-17:24:48.362  INFO [ttScheduler-1] CacheManager[109] - end update  configuration
...
...

更新:我已经修复了打字错误:到修复延迟(生成相同的输出)该应用程序是一个在tomcat8下运行的web应用程序。

我按照德米特里·哈米托夫的建议制作了一个小应用程序(这次不是网络)。它确实可以作为一个单独的可执行应用程序工作,但正如我写的一样,同样的代码在web应用程序环境下不起作用。

工作测试代码示例:

public class SpringTestApplication {
private final AtomicInteger counter = new AtomicInteger();
public void updateConfigurations() throws InterruptedException {
if (counter.getAndIncrement() == 0) {
Date instant = new Date(System.currentTimeMillis());
SimpleDateFormat sdf = new SimpleDateFormat( "HH:mm:ss" );
String time = sdf.format( instant );
System.out.println( "Time: " + time );
Thread.sleep(5000);
}
Date instant = new Date(System.currentTimeMillis());
SimpleDateFormat sdf = new SimpleDateFormat( "HH:mm:ss" );
String time = sdf.format( instant );
System.out.println( "Time: " + time );
}
public static void main(String[] args) {
new ClassPathXmlApplicationContext("spring.xml");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/task 
http://www.springframework.org/schema/task/spring-task-4.2.xsd
http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<bean id="SpringTestApplication" class="com.example.demo.SpringTestApplication" scope="singleton">
</bean>
<task:scheduler id="ttScheduler" pool-size="1"/>
<task:scheduled-tasks scheduler="ttScheduler">
<task:scheduled ref="SpringTestApplication" method="updateConfigurations" fixed-delay="5000" initial-delay="0"/>
</task:scheduled-tasks>

</beans>

这可能是因为在XML中使用固定速率,而在Java配置中使用固定延迟。正如春季官方文件所述:

固定延迟指示每次任务执行完成后等待的毫秒数。另一个选项是固定速率,指示无论以前的执行需要多长时间,都应该执行该方法的频率。。。

因此,如果您的示例中的某些代码在某个时间间隔内花费的时间远远超过固定速率,那么连续的任务可能只是在该时间间隔内排队。一旦完成了繁重的执行,并且接下来的执行恰好是轻量级的,那么您将在日志中看到您所看到的内容,直到ScheduledExecutorService的队列被耗尽。在那之后,你的轻量级任务将开始运行每固定的速率ms。

尝试在日志中搜索第一次执行,以查看它们所花费的时间。您也可以注释掉一些代码,然后重新启动应用程序,试图找到根本原因。下面是我的模拟示例,预计每1秒运行一次,但第一次运行需要5秒:

public class CacheManager {
private static final Logger LOG = LoggerFactory.getLogger(CacheManager.class);
private final AtomicInteger counter = new AtomicInteger();
public void updateConfigurations() throws InterruptedException {
LOG.info("update configurations");
if (counter.getAndIncrement() == 0) {
Thread.sleep(5000);
}
LOG.info("end update configurations");
}
public static void main(String[] args) {
new ClassPathXmlApplicationContext("spring.xml");
}
}
<beans ...>
<bean id="cacheManager" class="CacheManager"/>
<task:scheduler id="ttScheduler" pool-size="1"/>
<task:scheduled-tasks scheduler="ttScheduler">
<task:scheduled ref="cacheManager" method="updateConfigurations" fixed-rate="1000" initial-delay="0"/>
</task:scheduled-tasks>
</beans>

输出:

21:00:58.703 [ttScheduler-1] INFO  CacheManager - update configurations
21:01:03.706 [ttScheduler-1] INFO  CacheManager - end update configurations
21:01:03.706 [ttScheduler-1] INFO  CacheManager - update configurations
21:01:03.707 [ttScheduler-1] INFO  CacheManager - end update configurations
21:01:03.707 [ttScheduler-1] INFO  CacheManager - update configurations
21:01:03.707 [ttScheduler-1] INFO  CacheManager - end update configurations
21:01:03.707 [ttScheduler-1] INFO  CacheManager - update configurations
21:01:03.707 [ttScheduler-1] INFO  CacheManager - end update configurations
21:01:03.707 [ttScheduler-1] INFO  CacheManager - update configurations
21:01:03.708 [ttScheduler-1] INFO  CacheManager - end update configurations
21:01:03.708 [ttScheduler-1] INFO  CacheManager - update configurations
21:01:03.708 [ttScheduler-1] INFO  CacheManager - end update configurations
21:01:04.707 [ttScheduler-1] INFO  CacheManager - update configurations
21:01:04.708 [ttScheduler-1] INFO  CacheManager - end update configurations
21:01:05.706 [ttScheduler-1] INFO  CacheManager - update configurations
21:01:05.706 [ttScheduler-1] INFO  CacheManager - end update configurations
21:01:06.704 [ttScheduler-1] INFO  CacheManager - update configurations
21:01:06.704 [ttScheduler-1] INFO  CacheManager - end update configurations

最新更新