¿Con qué frecuencia se ejecuta un temporizador EJB creado programáticamente en un clúster?

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

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 el Singleton se instancia en cada nodo, por lo que el initResetTimer se realiza 3 veces en total (una vez por nodo). Entonces la pregunta es: es el caché borrado (executeResetTimer se invoca) en todos los nodos una vez por hora o no?

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

preguntado el 04 de julio de 12 a las 08:07

3 Respuestas

Primero, asegúrese de haber configurado el servicio de temporizador para la fuente de datos XA compartida externa como se describe aquí.

Habiendo profundizado en su pregunta en el pasado, recuerdo alguna explicación por desarrolladores en listas de correo, que la implementación de Glassfish es la siguiente:

Digamos 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 del temporizador se envían al nodo A). Si el nodo A falla, sus temporizadores se pueden migrar a otro nodo activo.

Tener ese Glassfish no es compatible en todo el grupo @Singletons, terminará con tantos temporizadores como llamadas a initResetTimer(). Además, cada reinicio/reimplementación del servidor posiblemente creará una nueva instancia de temporizador por nodo de clúster, además de las antiguas no canceladas, así que no olvide cancelar sus temporizadores creados mediante programación :) Para evitar esto por completo, use declarativo @Schedule(...) enfoque y Glassfish creará el temporizador una vez a través del clúster y, con suerte, migrarlos automáticamente en caso de falla.

Espero que esto ayude.

ACTUALIZACIÓN:

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

Respondido 13 Jul 12, 13:07

Esta respuesta fue muy útil y responde a otra pregunta: stackoverflow.com/questions/11244608/… -- Pero todavía hay una pregunta abierta: en el ejemplo anterior, el temporizador programático NO es persistente -- ¿se ejecutará en el mismo nodo (esto es lo que quiero lograr)? - Ralph

Sí, las llamadas programáticas a timerService.createXXXTimer(...) son independientes entre sí, consulte la actualización para responder. - Tair

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 dispararse una vez independientemente de la cantidad de nodos en el clúster. Dado que cada bean singleton (según su pregunta) llama createIntervalTimer, se ejecutará n veces. Esto es similar a creando temporizadores en ServletContextListener.

Aunque esto es teoría. Verificaría dos veces el servidor de aplicaciones específico al que se dirige. en pez cristal, temporizador de todo el clúster requiere configurar el grupo de temporizadores con una base de datos externa.

contestado el 23 de mayo de 17 a las 13:05

Incluso si no es una respuesta directa, esto podría ayudar de todos modos: una forma de configurar solo una instancia por entorno en clúster sería exponer el ejb único 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. Por último, tendría que proporcionar un gancho @PreDestroy para darse de baja del servicio jmx. Esta es la forma sugerida por el Campeón de Java Adam Bien.

Respondido 09 Jul 12, 10:07

Es una buena marca, pero no veo cómo se relaciona con mi problema. - Ralph

¿Podría vincular a donde Adam Bien describió esto? - Davids

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.