程序化创建的EJB Timer在集群中执行的频率是多少? [英] How often is a programmatic created EJB Timer executed in a cluster?
问题描述
在集群JEE6环境(Glassfish 3.1.2)中,可以在每个集群节点上创建 @Singleton
bean。如果这个Singleton Bean在其 @PostConstruct
上注册了一个编程计时器 - @Timeout
方法执行的频率是多少? - 只有一个单身人士(每个蜱),或每个Singeton注册一个计时器一次(每个蜱)?
In a clustered JEE6 environment (Glassfish 3.1.2), a @Singleton
bean is/can be created on every cluster node. If this Singleton Bean registers a programmatic timer on its @PostConstruct
- how often is the @Timeout
method executed? -- on only one of that singletons (per tick), or once (per tick) for each Singeton that registered that a timer?
代码下面是这个问题对这段代码意味着什么。
@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
)?
Example: The application runs on 3 nodes in a cluster. Assume the Singleton is instantiated on every node, so the initResetTimer
is done 3 times in total (once per node). Then the question is: is the cache cleared (executeResetTimer
is invoked) on all nodes once per hour or not?
(我知道计时器不会在所有节点上同时打勾,因为Singleton会在不同时间实例化,但这不是问题/问题。)
推荐答案
首先,确保按照描述这里。
在过去深入研究你的问题之后,我记得一些解释在邮件列表中的开发人员,Glassfish的实现如下:
Having digged into your question in past, I remember some explanation by devs in mailing-lists, that Glassfish's implementation is as follows:
假设您在群集中有节点A,B和C.在节点A创建的持久定时器
由节点A拥有(即定时器事件被传递到
节点A)。如果节点A失败,那么它的定时器可以迁移到另一个实时的
节点。
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 不支持群集范围 @Singletons
,你最终会得到与 initResetTimer()
的调用一样多的计时器。此外,每个服务器重新启动/重新部署可能会为每个群集节点创建一个新的计时器实例,此外还有旧的未删除的计时器,所以不要忘记取消以编程方式创建的计时器:)为了避免这种情况,请使用声明性的 @Schedule(...)
方法和Glassfish将创建计时器 一旦跨群集 ,并希望在失败时自动迁移它们。
Having that Glassfish doesn't support cluster-wide @Singletons
, you end up with as many timers as calls to initResetTimer()
. Moreover, each server restart/redeploy will possibly create a new instance of timer per cluster node, in additions to old uncancelled ones, so don't forget to cancel your programmatically created timers :) To avoid this alltogether use declarative @Schedule(...)
approach and Glassfish will create the timer once across cluster and, hopefully, automatically migrate them on failure.
希望这会有所帮助。
更新:
以编程方式创建的计时器(持久性或非持久性)将在创建它的JVM /节点中触发,无论集群设置或不。您可以粗略总结:独立计时器实例的数量等于对的调用次数timer.createXxxTimer()
A programmatically created timer, persistent or non-persistent, will be fired in the JVM/node it was created, regardless of clustered setup or not. You can sum up roughly: number of independent timer instances is equal to the number of calls to timer.createXxxTimer()
这篇关于程序化创建的EJB Timer在集群中执行的频率是多少?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!