【问题标题】:How to Use EJB 3.1 Automatic Non-Persistent Timer in Clustered Environment on Websphere?如何在 Websphere 的集群环境中使用 EJB 3.1 自动非持久定时器?
【发布时间】:2017-04-25 20:02:05
【问题描述】:

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

来自IBM Knowledge Center

集群环境中的计时器

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

我想使用持久计时器的这一功能(仅在一个集群成员上运行计时器),但我不想要“持久”功能,它指定计时器将在服务器重新启动或崩溃后继续存在尝试“赶上”无法触发的计时器事件。

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

【问题讨论】:

    标签: java timer ejb-3.1 websphere-8


    【解决方案1】:

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

    第一个选项:安排一个持久的 EJB 间隔计时器,该计时器调用 javax.ejb.Timer.getTimeRemaining 并在为负数时跳过自身。

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

    【讨论】:

    • 我认为 getTimeRemaining 建议不可靠。我记得,它总是会从超时回调方法中返回 0。也许我记错了,它返回(现在时间),但在这种情况下,一旦考虑到调用方法的开销,它通常会是负数(至少是间歇性的)。
    • 在发布答案之前,我确实在超时回调中尝试了 Timer.getTimeRemaining,其中错过了几次执行。我的计时器 - 计划每 2 秒运行一次 - 报告 Timer.getTimeRemaining 值为 (-15860, -13943, -11966, -9990, -8013, -6033, -4055, -2075, -97, 1883, 1984 年,...)。当处决之间再次开始延迟时,它从消极变为积极,完全赶上了错过的处决。我要补充一点,我只在 WebSphere Application Server Liberty 上尝试过这个,而不是传统的。行为可能不匹配。
    • 啊,也许在你的回答中澄清你的意思是一个间隔计时器而不是一个单一动作计时器,它对 getTimeRemaining 有不同的行为。 (无论如何,如果间隔足够小和/或系统负载足够,我认为即使对于非追赶调用,负 getTimeRemaining 的“误报”仍然存在风险,所以我不确定这个是一个强有力的建议。)
    • 谢谢,我已经添加了关于间隔计时器的说明,以防我误解了这个问题。关于误报的观点,我在这里不太同意。提出问题的人将最终决定,但我相信其意图是跳过追赶行为。无论是由于服务器关闭还是系统过载都无关紧要。如果 getTimeRemaining 有一个负值,那么一旦当前执行完成,下一个将开始,这是他们试图避免的。响应继续...
    • 如果有的话,我会质疑他们是否想在相反的方向上走得更远,并与重复间隔的某个部分的正值进行比较。例如,如果目标是每小时启动一个作业,可能需要最多 30 分钟才能运行,那么如果剩余时间少于 30 分钟,他们可能希望跳过启动该作业,因此他们将与 1800000 毫秒的值进行比较.
    猜你喜欢
    • 2012-02-23
    • 1970-01-01
    • 1970-01-01
    • 2014-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多