example java java-ee timer cluster-computing

java - ejb 3.0 timer service example



¿Con qué frecuencia se ejecuta un Temporizador EJB creado programáticamente en un clúster? (3)

Incluso si no es un resultado directo, esto podría ayudar de todos modos: una forma de configurar solo una instancia por entorno agrupado sería exponer el ejb singleton como MXbean. Debería tener que exponer una interfaz administrada, que incluso podría estar vacía, luego registrar su ejb en el servicio jmx en el método marcado @PostCostruct. Finalmente, debería proporcionar un gancho @PreDestroy para cancelar el registro del servicio de jmx. Este es el camino sugerido por el Campeón de Java Adam Bien.

En un entorno agrupado JEE6 (Glassfish 3.1.2), se puede / @Singleton un @Singleton bean en cada nodo del clúster. Si este Singleton Bean registra un temporizador programático en su @PostConstruct , ¿con qué frecuencia se @Timeout método @Timeout ? - en solo uno de esos singletons (por tick), o una vez (por tick) para cada Singeton que registró ese timer?

Debajo del código hay un ejemplo de lo que significa esta pregunta para este código.

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

Ejemplo: la aplicación se ejecuta en 3 nodos en un clúster. Supongamos que Singleton se initResetTimer instancia en cada nodo, por lo que el initResetTimer se realiza 3 veces en total (una vez por nodo). Entonces la pregunta es: ¿ se borra la caché (se invoca executeResetTimer ) en todos los nodos una vez por hora o no?

(Sé que el temporizador no marca al mismo tiempo en todos los nodos, porque el Singleton se instancia en diferentes momentos, pero este no es el problema / pregunta).


En primer lugar, asegúrese de haber configurado el servicio de temporizador a un origen de datos XA compartido externo como se describe aquí .

Después de haber profundizado en su pregunta en el pasado, recuerdo alguna explicación de los desarrolladores en las listas de correo, que la implementación de Glassfish es la siguiente:

Supongamos que tiene el nodo A, B y C en un clúster. Los temporizadores persistentes creados en el nodo A son "propiedad" del nodo A (es decir, los eventos temporizadores se entregan al nodo A). Si el nodo A falla, sus temporizadores se pueden migrar a otro nodo activo.

Teniendo que Glassfish no es compatible con @Singletons todo el @Singletons , terminas con tantos temporizadores como llamadas a initResetTimer() . Además, cada reinicio / redistribución del servidor posiblemente creará una nueva instancia de temporizador por nodo del clúster, además de los no anulados antiguos, así que no olvide cancelar los temporizadores creados por programación :) Para evitar esto, utilice el declarativo @Schedule(...) approach y Glassfish creará el temporizador una vez en el clúster y, con suerte, migrará automáticamente en caso de fallo.

Espero que esto ayude.

ACTUALIZAR:

Un temporizador creado mediante programación, persistente o no persistente, se activará en la JVM / nodo que se creó, independientemente de la configuración agrupada o no. Puede resumir aproximadamente: el número de instancias de temporizador independientes es igual al número de llamadas a timer.createXxxTimer()


Eché un vistazo al capítulo 18 "Servicio de temporizador" de la especificación EJB 3.1. La aplicación debe comportarse de acuerdo con la especificación independientemente de la agrupación.

Tengo entendido que si createIntervalTimer se llama una vez en un clúster, el temporizador debe disparar una vez independientemente en la cantidad de nodos en el clúster. Como cada bean singleton (según su pregunta) llama a createIntervalTimer , se ejecutará n veces. Es similar a crear temporizadores en ServletContextListener .

Esta es la teoría, sin embargo. Verificaría dos veces el servidor de aplicaciones específico al que apunta. En glassfish, el temporizador de todo el clúster requiere configurar el grupo de temporizadores con una base de datos externa.