java – 在集群中执行程序化创建的EJB Timer的频率是多少?

在集群JEE6环境(Glassfish 3.1.2)中,可以在每个集群节点上创建@Singleton bean.如果这个Singleton Bean在其@PostConstruct上注册一个编程定时器 – @Timeout方法执行的频率是多少? – 只有一个单身人士(每个蜱),或每个Singeton注册一个计时器一次(每个蜱)?

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

@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会在不同时间实例化,但这不是问题/问题.)

最佳答案
首先,确保您对外部共享XA数据源设置了定时器服务,如here所述.

在过去深入研究你的问题之后,我记得some explanation by devs in mailing-lists,Glassfish的实现如下:

Say you have node A, B and C in a cluster. Persistent timers created
at node A are “owned” by node A (that is timer-events are delivered to
node A). If node A fails, then its timers can be migrated to another live
node.

拥有Glassfish doesn’t support集群范围的@Singletons,您最终会得到与initResetTimer()调用一样多的计时器.此外,每个服务器重新启动/重新部署可能会为每个群集节点创建一个新的计时器实例,此外还有旧的未删除的计时器,所以不要忘记取消以编程方式创建的计时器:)为了避免这一点,请使用声明式@Schedule(.. .)方法和Glassfish将创建计时器once across cluster,并希望在失败时自动迁移它们.

希望这可以帮助.

更新:

无论集群设置如何,将在创建它的JVM /节点中触发以编程方式创建的持久性或非持久性计时器.你可以大致总结一下:独立定时器实例的数量等于对timer.createXxxTimer()的调用次数.

转载注明原文:java – 在集群中执行程序化创建的EJB Timer的频率是多少? - 代码日志