web-applications - management - locking infinispan




Infinispan Jgroups Si blocca dopo la guerra (2)

Sto lavorando su Wildfly 9 con Infinispan 7.2.3.

Sto affrontando uno strano problema relativo alla cache distribuita:

  1. Sul server delle applicazioni ho N guerre distribuite che espongono i servizi REST
  2. Ogni codice di servizio ha il dovere comune di verificare se un CacheManager è già presente su JNDI, in caso affermativo lo utilizza altrimenti ne creo uno nuovo e lo associa al JNDI. Quindi ogni guerra funziona con un'istanza CacheManager unica.
  3. Infinispan CacheManager è configurato in modalità distribuita.

L'infinispan e i jgroup sono forniti dal server delle applicazioni. Dopo un'operazione di re-deploy (undploy e deploy) di tutte le guerre, se improvvisamente inizio a inviare la richiesta REST a questi servizi ottengo questo errore:

18:23:42,366 WARN  [org.infinispan.topology.ClusterTopologyManagerImpl] (transport-thread--p2-t12) ISPN000197: Error updating cluster member list: org.infinispan.util.concurrent.Timeout
Exception: Replication timeout for ws-7-aor-58034
    at org.infinispan.remoting.transport.AbstractTransport.parseResponseAndAddToResponseList(AbstractTransport.java:87)
    at org.infinispan.remoting.transport.jgroups.JGroupsTransport.invokeRemotely(JGroupsTransport.java:586)
    at org.infinispan.topology.ClusterTopologyManagerImpl.confirmMembersAvailable(ClusterTopologyManagerImpl.java:402)
    at org.infinispan.topology.ClusterTopologyManagerImpl.updateCacheMembers(ClusterTopologyManagerImpl.java:393)
    at org.infinispan.topology.ClusterTopologyManagerImpl.handleClusterView(ClusterTopologyManagerImpl.java:309)
    at org.infinispan.topology.ClusterTopologyManagerImpl$ClusterViewListener$1.run(ClusterTopologyManagerImpl.java:590)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

18:23:42,539 WARN  [org.infinispan.topology.ClusterTopologyManagerImpl] (remote-thread--p11-t2) ISPN000329: Unable to read rebalancing status from coordinator ws-7-aor-19211: org.infinispan.util.concurrent.TimeoutException: Node ws-7-aor-19211 timed out
    at org.infinispan.remoting.transport.jgroups.CommandAwareRpcDispatcher.invokeRemoteCommand(CommandAwareRpcDispatcher.java:248)
    at org.infinispan.remoting.transport.jgroups.JGroupsTransport.invokeRemotely(JGroupsTransport.java:561)
    at org.infinispan.topology.ClusterTopologyManagerImpl.fetchRebalancingStatusFromCoordinator(ClusterTopologyManagerImpl.java:129)
    at org.infinispan.topology.ClusterTopologyManagerImpl.start(ClusterTopologyManagerImpl.java:118)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.infinispan.commons.util.ReflectionUtil.invokeAccessibly(ReflectionUtil.java:168)
    at org.infinispan.factories.AbstractComponentRegistry$PrioritizedMethod.invoke(AbstractComponentRegistry.java:869)
    at org.infinispan.factories.AbstractComponentRegistry.invokeStartMethods(AbstractComponentRegistry.java:638)
    at org.infinispan.factories.AbstractComponentRegistry.registerComponentInternal(AbstractComponentRegistry.java:207)
    at org.infinispan.factories.AbstractComponentRegistry.registerComponent(AbstractComponentRegistry.java:156)
    at org.infinispan.factories.AbstractComponentRegistry.getOrCreateComponent(AbstractComponentRegistry.java:277)
    at org.infinispan.factories.AbstractComponentRegistry.invokeInjectionMethod(AbstractComponentRegistry.java:227)
    at org.infinispan.factories.AbstractComponentRegistry.wireDependencies(AbstractComponentRegistry.java:132)
    at org.infinispan.remoting.inboundhandler.GlobalInboundInvocationHandler$2.run(GlobalInboundInvocationHandler.java:156)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.jgroups.TimeoutException: timeout waiting for response from ws-7-aor-19211, request: [email protected], req_id=6, mode=GET_ALL, target=ws-7-aor-19211
    at org.jgroups.blocks.MessageDispatcher.sendMessage(MessageDispatcher.java:427)
    at org.infinispan.remoting.transport.jgroups.CommandAwareRpcDispatcher.processSingleCall(CommandAwareRpcDispatcher.java:433)
    at org.infinispan.remoting.transport.jgroups.CommandAwareRpcDispatcher.invokeRemoteCommand(CommandAwareRpcDispatcher.java:241)
    ... 19 more

Questo è il codice di inizializzazione per il gestore cache:

    try {
            ctx = new InitialContext();
            cacheManager = (DefaultCacheManager)ctx.lookup(SessionConstants.CACHE_MANAGER_GLOBAL_JNDI_NAME);
        } catch (NamingException e1) {
            logger.error("SessionHooverJob not able to find: java:global/klopotekCacheManager ... a new instance will be created!");            
        }

        if (cacheManager ==null){ 

         ...
       configurator = ConfiguratorFactory.getStackConfigurator("default-configs/default-jgroups-udp.xml");
                ProtocolConfiguration udpConfiguration = configurator.getProtocolStack().get(0);
                if ("UDP".equalsIgnoreCase(udpConfiguration.getProtocolName()) && mcastAddr != null){
                    udpConfiguration.getProperties().put("mcast_addr", mcastAddr);
                }               
                GlobalConfigurationBuilder gcb = new GlobalConfigurationBuilder();
                gcb.globalJmxStatistics().enabled(true).allowDuplicateDomains(true);
                gcb.transport().defaultTransport()
                .addProperty(JGroupsTransport.CONFIGURATION_STRING, configurator.getProtocolStackString());
                //.addProperty(JGroupsTransport.CONFIGURATION_FILE, "config/jgroups.xml");

                ConfigurationBuilder builder = new ConfigurationBuilder();
                builder.clustering().cacheMode(CacheMode.DIST_SYNC).expiration().lifespan(24l, TimeUnit.HOURS);;

                cacheManager = new DefaultCacheManager(gcb.build(), 
                        builder.build());

Il problema non si verifica se trascorre un tempo di circa 40-60 secondi dopo la distribuzione. Se ho 1 gestore di sessione JNDI che ha costruito il canale jgroups, anche se non applico tutta la guerra ... perché jgroup tenta di fare di nuovo il bilanciamento?

C'è qualche proprietà di configurazione da impostare?


Non si suppone che si utilizzino le librerie Infinispan / JGroup fornite da Wildfly e JNDI non è in realtà il modo consigliato per condividere istanze di Cache / CacheManager.

Invece, dovresti distribuire la tua versione di Infinispan / JGroups, e quindi usare cose come CDI per iniettare CacheManager dove ti serve. Questo quickstart mostra come è possibile farlo utilizzando JBoss Data Grid, che è la versione supportata di Infinispan.

Il repository contiene altri quickstart come questo centrati sull'iniezione CDI di istanze Infinispan Cache e JSR-107 Cache .


Non c'è niente di sbagliato nell'usare le cache dal sottosistema Infinispan di WildFly, anche tramite JNDI, purché siano a conoscenza dei requisiti / vincoli del ciclo di vita delle risorse Infinispan gestite dal server. In WildFly, tutte le risorse Infinispan vengono create / avviate su richiesta, inclusi i gestori cache, le configurazioni della cache e le cache. Se nessun servizio richiede una determinata risorsa Infinispan, non viene avviato (né è associato a JNDI). Allo stesso modo, quando nessun servizio richiede più una determinata risorsa Infinispan, viene interrotto (e il suo binding JNDI rimosso). Pertanto, per cercare una risorsa Infinispan tramite JNDI, è necessario prima forzare l'avvio. Il modo più semplice per farlo è quello di creare un riferimento risorsa (cioè un resource-ref o resource-env-ref). per esempio

<resource-ref>
    <res-ref-name>infinispan/mycontainer</res-ref-name>
    <lookup-name>java:jboss/infinispan/container/mycontainer</lookup-name>
</resource-ref>

È ora possibile cercare il gestore della cache nello spazio dei nomi jndi dell'applicazione. per esempio

Context ctx = new InitialContext();
EmbeddedCacheManager manager = (EmbeddedCacheManager) ctx.lookup("java:comp/env/infinispan/mycontainer");

Il gestore cache sarà già avviato. Inoltre, non tentare mai di arrestare un gestore cache gestito dal server. Inoltre, non è possibile garantire che siano installate le configurazioni della cache definite nel sottosistema Infinispan per questo contenitore. Pertanto, l'uso dei getCache("...") non è un modo affidabile per ottenere un riferimento a una cache gestita dal server. Se si desidera dipendere da una cache specifica come definita nel sottosistema, si creerà un riferimento risorsa per la cache stessa. per esempio

<resource-ref>
    <res-ref-name>infinispan/mycache</res-ref-name>
    <lookup-name>java:jboss/infinispan/cache/mycontainer/mycache</lookup-name>
</resource-ref>

Ora puoi cercare direttamente nella cache.

Cache<?, ?> cache = (Cache) ctx.lookup("java:comp/env/infinispan/mycache");

La cache sarà già stata avviata. Allo stesso modo, non si dovrebbe tentare di arrestare una cache gestita dal server. Si fermerà automaticamente quando l'applicazione non viene distribuita o il server viene arrestato.