繁体   English   中英

使@Schedule仅在群集环境中运行一次

[英]Making @Schedule run only once in a clustered environment

我有两个tomee实例聚集。

每个人都有一个注释方法

@Schedule(dayOfWeek = "*")
public void runMeDaily() {...}

我想每天只运行一次这种方法。 一天不两次(每个实例一个)

我可以使用此处描述的标志仅在一个WebLogic群集节点上运行@Scheduled任务? 或者只选择一些节点,但我想知道是否有更优雅的方式来做到这一点。

这个问题与集群环境中的EJB3.1 @Schedule有些相关,但我没有使用JBOSS。 (而且没有回答)

我使用与其他线程相同的方法 - 检查特定主机是否正确运行作业。 但..

我不是非常有用的工具,但在春天你可以使用配置文件。 您可以找到适合您需求的类似解决方案。 看看http://spring.io/blog/2011/06/21/spring-3-1-m2-testing-with-configuration-classes-and-profiles

您可以定义两个单独的bean:

@Configuration
@Profile("dev")
public class StandaloneDataConfig {

@Bean
public DataSource dataSource() {
    return new EmbeddedDatabaseBuilder()
        .setType(EmbeddedDatabaseType.HSQL)
        .addScript("classpath:com/bank/config/sql/schema.sql")
        .addScript("classpath:com/bank/config/sql/test-data.sql")
        .build();
}
}

@Configuration
@Profile("production")
public class JndiDataConfig {

@Bean
public DataSource dataSource() throws Exception {
    Context ctx = new InitialContext();
    return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
}
}

并通过切换配置文件来决定打开哪一个。 所以带有注释@Scheduled方法的类只会加载特定的配置文件。 当然,您需要配置您的应用程序才能打开节点上的配置文件。 在Spring应用程序中,它就像将-Dspring.profiles.active = profile传递给其中一个一样简单。

我只能使用特定于平台(专有)的非Java EE解决方案来解决这个问题。 就我而言,我使用的是TomEE +和Quartz。 在集群模式下运行Quartz(org.quartz.jobStore.isClustered = true)并将计时器保存在单个数据库中会强制Quartz选择一个实例来触发计时器,因此它只运行一次。

这个链接非常有用 - http://rmannibucau.wordpress.com/2012/08/22/tomee-quartz-configuration-for-scheduled-methods/

遗憾的是,Java EE没有为此指定行为。 (但我希望):-)

我把一个盒子作为主人解决了这个问题。 基本上在其中一个框上设置一个环境变量,如master = true。

并通过system.getenv(“master”)在java代码中读取它。 如果它的存在和它的真实然后运行你的代码。

基本片段

@schedule()
void process(){
boolean master=Boolean.parseBoolean(system.getenv("master"));
if(master)
{
   //your logic
}

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM