Spring task:scheduler XML 配置问题
Spring task:scheduler XML configuration problem
我在 Bean 中有一些函数,我想每 5 秒 运行 变量应该是 "generalized" 不是硬编码:
工作代码如下:(我已经写在相关的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
...
...
更新:我已经修复了拼写错误:固定延迟(生成相同的输出)
该应用程序是 运行 在 tomcat 8.
下的网络应用程序
我按照 Dmitry Khamitov 的建议制作了小应用程序(这次不是网络)。它确实可以作为单个可执行应用程序工作,但仍然像我编写的相同代码一样在网络应用程序环境下无法工作。
工作测试代码示例:
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 配置中您使用固定延迟。正如 Official Spring Doc 所述:
...fixed delay indicating the number of milliseconds to wait after each task execution has completed. Another option is fixed-rate, indicating how often the method should be executed regardless of how long any previous execution takes...
因此,如果您的示例中的某些代码在某个时间间隔内花费的时间比您的固定速率多得多,那么连续的任务可能只是在该时间间隔内排队。一旦该繁重的执行完成并且如果下一次执行恰好是轻量级的,那么您将看到您在日志中看到的内容,直到 ScheduledExecutorService 的队列被耗尽。之后,您的轻量级任务将开始 运行 每固定速率毫秒。
尝试在日志中搜索第一次执行以查看它们所花费的时间。您还可以注释掉 Some Code 并重新启动您的应用程序以尝试找到根本原因。下面是我的模拟示例,预计每 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
我在 Bean 中有一些函数,我想每 5 秒 运行 变量应该是 "generalized" 不是硬编码:
工作代码如下:(我已经写在相关的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
...
...
更新:我已经修复了拼写错误:固定延迟(生成相同的输出) 该应用程序是 运行 在 tomcat 8.
下的网络应用程序我按照 Dmitry Khamitov 的建议制作了小应用程序(这次不是网络)。它确实可以作为单个可执行应用程序工作,但仍然像我编写的相同代码一样在网络应用程序环境下无法工作。
工作测试代码示例:
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 配置中您使用固定延迟。正如 Official Spring Doc 所述:
...fixed delay indicating the number of milliseconds to wait after each task execution has completed. Another option is fixed-rate, indicating how often the method should be executed regardless of how long any previous execution takes...
因此,如果您的示例中的某些代码在某个时间间隔内花费的时间比您的固定速率多得多,那么连续的任务可能只是在该时间间隔内排队。一旦该繁重的执行完成并且如果下一次执行恰好是轻量级的,那么您将看到您在日志中看到的内容,直到 ScheduledExecutorService 的队列被耗尽。之后,您的轻量级任务将开始 运行 每固定速率毫秒。
尝试在日志中搜索第一次执行以查看它们所花费的时间。您还可以注释掉 Some Code 并重新启动您的应用程序以尝试找到根本原因。下面是我的模拟示例,预计每 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