Java 如何在Websphere上的集群环境中使用EJB3.1自动非持久计时器?

Java 如何在Websphere上的集群环境中使用EJB3.1自动非持久计时器?,java,timer,ejb-3.1,websphere-8,Java,Timer,Ejb 3.1,Websphere 8,关于集群环境中的自动(使用@Schedule)持久和非持久计时器,文档中指出,持久计时器仅在一个集群成员中运行,自动非持久计时器在包含EJB的每个集群成员中运行: 发件人: 集群环境中的计时器 在集群环境中,持久计时器仅在一个集群中运行 可能不一定是同一群集成员的群集成员 它是在年创建的。在每个集群成员中运行一个非持久性计时器 它是在中创建的-自动非持久计时器在每个 包含EJB的集群成员 我希望使用持久计时器的此功能(仅在一个集群成员上运行计时器),但我不希望使用“持久”功能,该功能指定计时器将

关于集群环境中的自动(使用@Schedule)持久和非持久计时器,文档中指出,持久计时器仅在一个集群成员中运行,自动非持久计时器在包含EJB的每个集群成员中运行:

发件人:

集群环境中的计时器

在集群环境中,持久计时器仅在一个集群中运行 可能不一定是同一群集成员的群集成员 它是在年创建的。在每个集群成员中运行一个非持久性计时器 它是在中创建的-自动非持久计时器在每个 包含EJB的集群成员

我希望使用持久计时器的此功能(仅在一个集群成员上运行计时器),但我不希望使用“持久”功能,该功能指定计时器将在服务器重新启动或崩溃后存活,并尝试“跟踪”无法触发的计时器事件


有没有办法让一个自动的非持久计时器只在一个集群成员上运行?或者,是否可以关闭持久计时器的“追赶”功能?

您所要求的功能(仅在一个集群成员上运行且没有“追赶”以前错过的过期时间的非持久计时器)未内置到WebSphere Application Server中。但是,有几种方法可以模拟它

第一个选项:计划一个持久的EJB间隔计时器,该计时器调用javax.EJB.timer.getTimeRestaining,并在为负时跳过自身


第二个选项:在每个成员上安排一个非持久计时器。使用数据库或其他持久性存储记录最近尝试执行的时间戳。当非持久性计时器尝试运行时,如果持久性存储最近没有运行,则尝试更新持久性存储以将时间戳替换为当前时间戳。如果成功,则运行计时器,否则不运行。如果集群成员相对较少,这可能会很好地工作,否则数据库上可能会有太多争用。

我认为GetTimeResisting建议不可靠。我记得,它总是在超时回调方法中返回0。也许我记错了,它返回(time now),但在这种情况下,一旦考虑到调用该方法的开销,它通常是负的(至少是间歇性的)。在发布答案之前,我尝试了Timer.getTimeRemaining,它位于timeout回调中,在该回调中错过了多次执行。我的计时器(计划每2秒运行一次)报告了timer.GetTime剩余值(-15860,-13943,-11966,-9990,-8013,-6033,-4055,-2075,-9718831984,…)。当两次执行之间再次出现延迟时,它从负变为正,完全赶上了错过的执行。我要补充的是,我只在WebSphereApplicationServerLiberty上尝试过这个,而不是传统的。行为可能不匹配。啊,也许在你的回答中澄清一下,你指的是一个间隔计时器,而不是一个动作计时器,它的getTimeResisting行为不同。(不管怎样,如果间隔足够小和/或系统负载足够大,我认为即使对于非赶超调用,仍然存在负gettimereserving的“误报”风险,因此我不确定这是一个可靠的建议。)谢谢,我已经添加了关于间隔计时器的说明,以防我误解了这个问题。关于假阳性的观点,我在这里并不完全同意。问这个问题的人最终会做出决定,但我相信其意图是跳过追赶行为。无论是由于服务器停机还是系统负载过大,这都不重要。如果getTimeRemaining有一个负值,那么当前执行一结束,下一个将开始,这正是他们试图避免的。回答继续…如果有什么问题的话,我想问他们是否想朝相反的方向走得更远,并与重复间隔的某个部分的正值进行比较。例如,如果目标是每小时启动一个作业,该作业可能需要30分钟才能运行,那么如果剩余时间不足30分钟,则他们可能希望跳过启动作业,因此他们将与1800000ms的值进行比较。