Java Spring shedlock 失败

问题描述 投票:0回答:2

我有一个 spring-boot 应用程序,它在生产环境中运行在 2 个实例中,导致计划任务运行两次。为了避免这种情况,我尝试使用 shedlock,如herehere所解释,但它没有任何影响。 我已经在使用 MySql 数据库,我在其中添加了一个

shedlock
表,如上面两个示例中所述。

我的项目结构如下(部分)-

在我的

application.properties
文件中我有这个设置-

db.driver=com.mysql.cj.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/b4ad?autoReconnect=true&useSSL=false&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
db.username=*****
db.password=*****

AppConfig
类中我添加了此注释 -

@EnableSchedulerLock(defaultLockAtMostFor = "PT30S")

还有这颗豆子 -

@Bean
public LockProvider lockProvider(DataSource dataSource) {
    return new JdbcTemplateLockProvider(dataSource, "b4ad.shedlock");
}

ScheduledManager
课上我有这个计划任务-

 @Scheduled(cron = "0 0/1 * * * ?")
@SchedulerLock(name = "deactivateExpiredOrganizations", lockAtLeastFor = "PT5M")
public void deactivateExpiredOrganizations() {
    // my code...
}

当我在 2 个实例上本地运行应用程序时(使用

application.properties
文件中的 2 个不同端口),查看日志我可以看到任务在两个实例上运行,同时
shedlock
表保持为空。 根据故障排除部分中的第二项,我似乎错过了一些配置,但我不知道是什么。

任何帮助将不胜感激。

java spring-boot scheduled-tasks shedlock
2个回答
0
投票

好吧,显然在我的大项目中还有另一个配置类(除了

AppConfig
之外)——一个名为
SqlSpringConfig
,位于 db 模块内。 一旦我把
LockProvider
豆子放在那里,一切都会像魅力一样发挥作用


0
投票

您应该检查您的任务配置实现。

我的项目也有同样的问题。问题出在下面的代码中。

@Configuration
public class SchedulerConfig implements SchedulingConfigurer {
    private final int POOL_SIZE = 10;

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();

        threadPoolTaskScheduler.setPoolSize(POOL_SIZE);
        threadPoolTaskScheduler.setThreadNamePrefix("my-scheduled-task-pool-");
        threadPoolTaskScheduler.initialize();

        scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
    }
}

我们通过实现 ScheduledTaskRegistrar 添加自定义配置,以使用多线程执行任务。但如果你覆盖configureTasks,shedlock就不起作用。您应该使用@Bean 进行注入。所以,

    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
    
        threadPoolTaskScheduler.setPoolSize(POOL_SIZE);
        threadPoolTaskScheduler.setThreadNamePrefix("custom-scheduler-");
        threadPoolTaskScheduler.initialize();
    
        return threadPoolTaskScheduler;
    }

当我将覆盖更改为通过@Bean注入时,效果很好!

© www.soinside.com 2019 - 2024. All rights reserved.