How often is a software-generated EJB Timer created running in a cluster?

In a JEE6 cluster environment (Glassfish 3.1.2), @Singleton bean can be created in each node cluster. If this Singleton bean registers a program timer with @PostConstruct - how often does the @Timeout method @Timeout ? - only on one of these singletons (for a tick) or once (for a mark) for each Singeton who registered the timer?

The code below is an example of what this question means for this code.

 @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(); } } 

Example: an application runs on 3 nodes in a cluster. Suppose a Singleton is created on each node, so initResetTimer runs 3 times (once per node). Then the question arises: is the cache cleared ( executeResetTimer called) on all nodes once an hour or not?

(I know that the timer does not tick on all nodes at the same time, because Singleton is created at different times, but this is not a problem / question.)

+4
source share
3 answers

First, make sure you configure the timer service to an external XA shared data source, as described here .

After delving into your question in the past, I remember some explanation from the developers on the mailing lists that the Glassfish implementation looks like this:

Say you have node A, B and C in the cluster. Permanent timers are created when node A "belongs" to node A (that is, timer events are delivered by node A). If node A fails, then its timers can be moved to another node.

After Glassfish does not support the @Singletons cluster, you get as many timers as there are calls to initResetTimer() . In addition, each restart / restart of the server will probably create a new timer instance on the node cluster, in addition to the old unspecified ones, so be sure to cancel your programmatically created timers :) To avoid this alltogether, use declarative @Schedule(...) approach and Glassfish will create a timer once in the cluster and, hopefully, automatically transfer them on error.

Hope this helps.

UPDATE:

A programmatically created timer, permanent or intermittent, will be launched in the JVM / node, it was created regardless of clustering or not. You can summarize approximately: the number of independent timer instances is equal to the number of calls timer.createXxxTimer()

+2
source

I took a look at Chapter 18, Timer Service, of the EJB 3.1 specification. The application should behave according to the specification regardless of clustering.

I understand that if createIntervalTimer is called once in a cluster, the timer should start once, regardless of the number of nodes in the cluster. Since every singleton bean (according to your question) calls createIntervalTimer , it will be executed n times. It is like creating timers in a ServletContextListener .

This is a theory. I would double check for a specific target application server. In glassfish, a cluster timer is required to configure a timer pool with an external database.

+2
source

Even if this is not a direct answer, it can help in any case: one way that will configure only one instance for a clustered environment is to expose singleton ejb as an MXbean. You will need to open a managed imterface, which may even be empty, and then register ejb in the jmx service in the method marked by @PostCostruct. Finally, you will need to provide the @PreDestroy hook to unregister from the jmx service. This is the method suggested by the Java Champion Adam Bien.

+1
source

Source: https://habr.com/ru/post/919236/


All Articles