首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >程序创建的EJB计时器在集群中多久执行一次?

程序创建的EJB计时器在集群中多久执行一次?
EN

Stack Overflow用户
提问于 2012-07-04 07:39:56
回答 3查看 6.6K关注 0票数 4

在集群JEE6环境(Glassfish 3.1.2)中,可以在每个集群节点上创建@Singleton bean。如果这个Singleton在它的@PostConstruct上注册了一个编程定时器-- @Timeout方法多久执行一次?--只在其中一个单点(每个滴答)上注册,或者对注册那个计时器的每个Singeton (每个滴答)只执行一次?

下面的代码是一个例子,这个问题对这段代码意味着什么。

代码语言:javascript
复制
@Singleton
public class CachedService {

@Resource
private TimerService timerService;

    private static final long CACHE_TIMEOUT_DURATION_MS = 60 * 60 * 1000;

    @PostConstruct
    void initResetTimer() {
        this.timerService.createIntervalTimer(CACHE_TIMEOUT_DURATION_MS,
            CACHE_TIMEOUT_DURATION_MS,
            new TimerConfig("current user cache timeout", false));
    }

    @Timeout
    public void executeResetTimer() {
        this.clearCache();
    }
}

示例:应用程序运行在集群中的3个节点上。假设在每个节点上实例化了Singleton,那么initResetTimer总共执行3次(每个节点一次)。那么问题是:是否每小时在所有节点上清除缓存(**executeResetTimer** )?

(我知道计时器不是同时在所有节点上运行,因为Singleton是在不同的时间实例化的,但这不是问题。)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-07-13 06:56:07

首先,确保您已经设置了外部共享XA数据源的计时器服务,如所述的这里

在过去深入研究过您的问题之后,我记得一些解释在邮件列表中使用了devs,Glassfish的实现如下:

假设集群中有节点A、B和C。在节点A中创建的持久定时器由节点A“拥有”(也就是说,计时器事件被传递到节点A)。如果节点A失败,则可以将其定时器迁移到另一个活动节点。

有了这个Glassfish 不支持集群范围的@Singletons,您的计时器就会和调用initResetTimer()一样多。此外,每台服务器重新启动/重新部署都可能为每个集群节点创建一个新的计时器实例,除了旧的未取消的计时器之外,所以不要忘记取消以编程方式创建的计时器:)为了避免这一切,使用声明式@Schedule(...)方法和Glassfish将创建计时器http://www.java.net/node/695110,并希望在失败时自动迁移它们。

希望这能有所帮助。

更新:

一个以编程方式创建的定时器,无论是否集群设置,都将在它创建的JVM/节点中触发。您可以大致总结:独立计时器实例的数量等于对timer.createXxxTimer()的调用数。

票数 4
EN

Stack Overflow用户

发布于 2012-07-04 11:53:53

我看了一下EJB3.1规范的第18章“计时器服务”。应用程序应该按照规范行事,而不是集群。

我的理解是,如果在集群中调用一次createIntervalTimer,则定时器应该对集群中的节点数独立地触发一次。因为每个单例bean (根据您的问题)都调用createIntervalTimer,所以它将执行n次。它类似于在ServletContextListener中创建计时器

不过这是理论。我会再次检查你针对的特定应用服务器。在glassfish中,集群范围计时器需要使用外部数据库配置计时器池。

票数 2
EN

Stack Overflow用户

发布于 2012-07-09 09:06:13

即使它不是一个直接的amswer,这也会有帮助:每一个集群环境只配置一个实例的一种方法是将单例ejb公开为MXbean。您应该公开一个托管的镜像,甚至可以是空的,然后在@PostCostruct标记方法中将ejb注册到jmx服务。最后,您必须提供一个@PreDestroy钩子,以便从jmx服务中取消注册。这是Java冠军Champion的建议。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11324514

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档