2012-06-17 9 views
20

Tengo una aplicación JEE6 que se ejecuta en un clúster Glassfish 3.1.2. Un @Singleton Bean contiene algún tipo de caché (readolny). Un usuario puede presionar un botón en la GUI para actualizar el caché con contenido (actualizado) de la base de datos.Cómo notificar a todos (el mismo) beans Singleton en un cluster Glassfish 3.1?

Esto funciona bien en un entorno sin clústeres, pero ahora tenemos que cambiar a un clúster.

Así que estoy enfrentando el problema, que cuando un usuario presiona ese botón de actualización, solo se actualiza el Singleton de caché de su nodo de servidor. Mi pregunta es, ¿cuál sería la forma más fácil de hacer que los otros Singleton (en los otros nodos) también actualicen los datos?

Conozco la pregunta Singleton in Cluster environment, pero mi pregunta es específica para Glassfish (porque espero que haya alguna versión en apoyo), la otra está relacionada con "Websphere". Y mi pregunta es sobre JEE6, la otra es más antigua que JEE6.

+1

Una cosa que es posible que desee publicar o pensar es 'qué tan rápido' necesita la actualización? alias, ¿cuál es su aislamiento de transacción requerido? ¿Necesita que el cambio se refleje en los singleton antes de que manejen cualquier otra solicitud? ¿O pueden procesar algunas llamadas y mientras reciban la actualización en unos pocos segundos? –

+0

@exabrial: unos segundos (1..5) están bien en mi escenario. – Ralph

+1

La mejor respuesta es el pub/sub con JMS, que Sam describe a continuación. Haz que un MDB se inyecte con una referencia al Singleton. El MDB debe suscribirse al tema. Haga que actualice el singleton cuando recibe un mensaje. –

Respuesta

10

GlassFish High Availability Administration Guide afirma explícitamente:

Restricciones

Al configurar la persistencia de sesiones y la conmutación por error, tenga en cuenta los siguientes restricciones:

  • Cuando una sesión por error, cualquier referencia a se pierden archivos abiertos o conexiones de red. Las aplicaciones se deben codificar con esta restricción en mente.

  • Los Singletons de EJB se crean para cada instancia de servidor en un clúster, y no una vez por clúster.

Otra sugerencia, sería utilizar JMS y tienen el botón de la GUI de prensa posterior un mensaje a un tema JMS. Todos los beans de Singleton pueden suscribirse a ese tema y recibir el mensaje hará que todos se actualicen desde la base de datos, casi al mismo tiempo.El beneficio de este enfoque es que aprovecha más las características integradas de Glassfish, sin tener necesariamente que incorporar otro marco.

En cualquier caso, pasar de una sola instancia a una instancia múltiple nunca es un cambio realmente fluido, y va a causar algunas dificultades. Probablemente será necesario realizar cambios en la aplicación para asegurarse de que todo el estado relevante (que no sea el estado de la sesión) se comparta correctamente con todas las instancias del clúster.

7

Desafortunadamente no hay una forma incorporada de lograr lo que quiere, pero el marco shoal que Glassfish basa en su agrupamiento podría ayudarlo aquí. Puede resolver el problema enviando notificaciones a los miembros del clúster para actualizar sus cachés o reemplazando su caché actual por una distribuida.

A continuación se muestra un ejemplo de uso del bajío para enviar notificaciones:

@Startup 
@Singleton 
public class Test { 

private String groupName = "mygroup"; 
private String serverName = System.getProperty("HTTP_LISTENER_PORT"); 
private GroupManagementService gms; 

@PostConstruct 
public void init() { 
    Runnable gmsRunnable = GMSFactory.startGMSModule(serverName, groupName, 
      GroupManagementService.MemberType.CORE, null); 
    gms = (GroupManagementService) gmsRunnable; 
    try { 
     gms.join(); 
     gms.addActionFactory(new MessageActionFactory() { 

      @Override 
      public Action produceAction() { 
       return new MessageAction() { 

        @Override 
        public void consumeSignal(Signal signal) 
          throws ActionException { 
         // Update your cache here 
        } 
       }; 
      } 
     }, groupName); 
    } catch (GMSException e) { 
     Logger.getAnonymousLogger().severe(e.getMessage()); 
    } 
} 

@PreDestroy 
public void cleanup() { 
    gms.shutdown(GMSConstants.shutdownType.INSTANCE_SHUTDOWN); 
} 

/** 
* Call this from your button click. 
*/ 
public void updateCache() { 
    try { 
     byte[] message = new byte[] {}; 
     gms.getGroupHandle().sendMessage(groupName, message); 
    } catch (GMSException e) { 
     Logger.getAnonymousLogger().severe(e.getMessage()); 
    } 
} 
} 

Si desea utilizar una memoria caché distribuida en su lugar:

  DistributedStateCache cache = gms.getGroupHandle().getDistributedStateCache(); 

Los elementos incluidos en la memoria caché se replicarán en el otro grupo nodos.

3

Eche un vistazo a JGroups. Es un marco para la comunicación confiable de multidifusión. Los mecanismos de clúster de JBoss se basan actualmente en esta herramienta.

Puede consultar un example usage of JGroups here.

Cuestiones relacionadas