在集群 Java EE 应用程序中实现为 @Singleton 的计划任务的并行化

Parallelization of a scheduled task implemented as @Singleton in a clustered Java EE application

我目前正在开发一个 Java EE 应用程序,它将部署在 Payara 服务器 4 上。payara 服务器在主机 1 上运行,还有 2 个实例(主机 1 和主机 2)可用作Payara 集群。

我遇到的问题是,如果我们在单例中调度一个任务class,那么该任务将同时执行三次。这个问题是2折的。


入口点如下所示。 (不是全部。)

@ApplicationScoped
@Singleton
public class StartClass {
    public void StartClass() {}
    public void init(@Observes @Initialized(ApplicationScoped.class) ServletContext) throws ... { ... }

    @Schedule(hour="*", minute="0", persistent=false)
    public void runJob() {
        MyClass my_class = new MyClass();
        my_class.do_the_job();
    }
}

这里我上面提到的定时任务是my_class.do_the_job()。这个方法只是往DB里插入一行,源码和this tutorial很像,有好几个System.out.println("DO_THE_JOB")。目标 table 有一列自动填充插入的时间戳。我还用 System.getenv("HOST") 放置了有关主机的信息。结果是我们每小时插入三行:主机 1 的 2 行和主机 2 的 1 行。但是 println() 的结果可以在日志文件中找到一次。

备注:

Why does this phenomenon happen?

仅仅是因为 Singleton bean 不可集群。这意味着集群的每个节点都有自己的 StartClass 实例。您可能会在类似的 SO .

上找到更多有用的信息

How can I avoid such multiple execution?

使用您当前的设置,您不能。您可能需要的是支持集群的调度程序。一个流行的选项是 quartz-scheduler,它支持集群。

在 JEE 规范中,没有办法拥有集群范围内的 @Singleton

解决此问题的一个可能选项是使用带有附加 @Clustered 注释的特定于 Payara 的集群单例。它从 Payara 4.182 开始可用。

在此处阅读更多相关信息 Payara clustered singleton