部署于Tomcat的Spring Boot调度器指定时间重复执行两次求助
Spring Boot @Scheduled调度器重复执行问题排查
问题描述
我在Spring Boot应用中编写了一个调度器,用于在指定时间同步相关信息。应用部署在采用UTC时区的Linux服务器的Tomcat中,未使用Docker,也没有多实例部署,仅安装Tomcat并部署Spring Boot WAR包。
遇到的问题是:调度器在指定时间执行了两次,日志显示两条带有不同traceId的“ClassLink sync Starting.”信息。
调度器代码如下:
@Scheduled(cron = "0 30 2 * * *", zone = "UTC") public void scheduleFixedDelayTask2() throws Exception { String traceId = controllerUtil.generateTracerId(); log.info(MessageConstants.API_LOG_INFO,traceId, LocalDateTime.now(), "ClassLink sync Starting." ); //classLinkService.fetchClassLinkData(traceId); log.info(MessageConstants.API_LOG_INFO,traceId, LocalDateTime.now(), "ClassLink sync finished." ); }
排查步骤
- 检查Tomcat的
webapps目录,确认是否同时存在WAR包和解压后的同名文件夹。Tomcat会自动解压WAR包,如果原WAR包未删除,可能导致应用被加载两次。 - 查看Tomcat启动日志,搜索
Root WebApplicationContext: initialization completed关键字,若出现两次,说明应用上下文被初始化了两次。 - 执行
ps aux | grep tomcat命令,检查服务器上是否有多个Tomcat进程在运行,若有则关闭多余进程并重启Tomcat。 - 确认项目中
@EnableScheduling注解的使用情况,确保仅在一个配置类中添加该注解,避免重复注册调度器上下文。 - 检查Tomcat的时区配置,在
catalina.sh或setenv.sh中查看是否设置了JAVA_OPTS="-Duser.timezone=UTC",确保与调度器指定的时区一致,避免时区差异导致的重复触发。 - 查看Spring Boot配置文件中的
spring.main.allow-bean-definition-overriding属性,若设置为true,改为false后重启应用,避免调度器Bean被重复创建。
内容的提问来源于stack exchange,提问作者david_23
相关产品推荐
相关产品推荐

