java java-ee synchronization glassfish cluster-computing

java - ¿Cómo notificar a todos(los mismos) frijoles Singleton en un cluster Glassfish 3.1?



java-ee synchronization (3)

Tengo una aplicación JEE6 que se ejecuta en un cluster Glassfish 3.1.2. One @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.

Esto funciona bien en un entorno sin agrupación, pero ahora necesitamos cambiar a una agrupación.

Así que estoy enfrentando el problema, que cuando un usuario presiona el 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 Singletons (en los otros nodos) también actualicen los datos?

Estoy al tanto de la pregunta Singleton en el entorno de Cluster , pero mi pregunta es específica para Glassfish (porque espero que exista cierta compatibilidad), la otra está relacionada con "Websphere". Y mi pregunta es sobre JEE6, la otra es más antigua que JEE6.


Desafortunadamente, no hay una forma integrada de lograr lo que desea, pero el marco de trabajo en el que Glassfish basa su agrupación 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 uno distribuido.

A continuación se muestra un ejemplo del uso de shoal 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 un caché distribuido en su lugar:

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

Los elementos colocados en el caché se replicarán en los otros nodos del clúster.


Echa un vistazo a JGroups . Es un framefork para la comunicación confiable de multidifusión. Los mecanismos de agrupación de JBoss se basan actualmente en esta herramienta.

Puedes ver un ejemplo de uso de JGroups aquí .


La Guía de administración de alta disponibilidad de GlassFish establece explícitamente:

Las restricciones

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

  • Cuando una sesión falla, todas las referencias a archivos abiertos o conexiones de red se pierden. Las solicitudes deben estar codificadas con esta restricción en mente.

  • Los Singletons 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 hacer que el botón GUI presione para enviar un mensaje a un tema JMS. Todos los beans Singleton pueden suscribirse a ese tema y recibir el mensaje hará que todos se actualicen desde la base de datos, casi simultáneamente. El beneficio de este enfoque, es que aprovecha más las características integradas de Glassfish, sin que necesariamente tenga que incorporar otro marco.

En cualquier caso, pasar de una instancia única a otra instancia nunca es un cambio realmente transparente, y va a causar alguna dificultad. Probablemente será necesario que haya 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.