Сбои Infinispan Jgroups после военного развертывания

Я работаю над Wildfly 9 с Infinispan 7.2.3.

Я столкнулся со странной проблемой, связанной с распределенным кешем:

  1. На сервере приложений у меня есть N развернутых войн, раскрывающих службы REST.
  2. Каждый сервисный код имеет общую обязанность проверять, присутствует ли уже CacheManager si в JNDI, если да, он использует его, в противном случае я создаю новый и привязываю его к JNDI. Таким образом, каждая война работает с уникальным экземпляром CacheManager.
  3. Infinispan CacheManager настроен в распределенном режиме.

Infinispan и jgroups предоставляются сервером приложений. После операции повторного развертывания (отмены развертывания и развертывания) всех войн, если я внезапно начну отправлять запрос REST этим службам, я получаю эту ошибку:

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: org.jgroups.blocks.UnicastRequest@75770aa6, 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

Это код инициализации для cachemanager:

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

Проблема не возникает, если после развертывания проходит около 40-60 секунд. Если у меня есть 1 диспетчер сеансов JNDI, который построил канал jgroups, даже если я отменю развертывание всей войны ... почему jgroups снова пытаются выполнить перебалансировку?

Есть ли какое-то свойство конфигурации для установки?


person Alex    schedule 27.07.2016    source источник


Ответы (2)


Нет ничего плохого в использовании кешей из подсистемы WildFly Infinispan, даже через JNDI, если вы осведомлены о требованиях/ограничениях жизненного цикла ресурсов Infinispan, управляемых сервером. В WildFly все ресурсы Infinispan создаются/запускаются по требованию, включая менеджеры кеша, конфигурации кеша и кеши. Если ни одна служба не требует данного ресурса Infinispan, она не запускается (и не привязывается к JNDI). Аналогичным образом, когда никакой службе больше не требуется данный ресурс Infinispan, он останавливается (и его привязка JNDI удаляется). Таким образом, для поиска ресурса Infinispan через JNDI необходимо сначала принудительно запустить его. Самый простой способ сделать это — создать ссылку на ресурс (т. е. resource-ref или resource-env-ref). например

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

Теперь вы можете найти диспетчер кеша в пространстве имен вашего приложения jndi. например

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

Менеджер кэша уже будет запущен. Кроме того, вы никогда не должны пытаться остановить менеджер кэша, управляемый сервером. Кроме того, нельзя гарантировать, что установлены какие-либо конфигурации кэша, определенные в подсистеме Infinispan для этого контейнера. Таким образом, использование методов getCache("...") не является надежным способом получения ссылки на кэш, управляемый сервером. Если вы хотите зависеть от определенного кеша, определенного в подсистеме, вы должны создать ссылку на ресурс для самого кеша. например

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

Теперь вы можете напрямую искать кэш.

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

Кэш уже будет запущен. Точно так же не следует пытаться остановить кэш, управляемый сервером. Он остановится автоматически, когда ваше приложение не будет развернуто или сервер будет выключен.

person Paul Ferraro    schedule 07.08.2016

Вы не должны использовать библиотеки Infinispan/JGroups, предоставляемые Wildfly, и JNDI не является рекомендуемым способом совместного использования экземпляров Cache/CacheManager.

Вместо этого вы должны развернуть свою собственную версию Infinispan/JGroups, а затем использовать такие вещи, как CDI, для внедрения CacheManager там, где вам это нужно. Это краткое руководство показывает как это можно сделать с помощью JBoss Data Grid, которая является поддерживаемой версией Infinispan.

Репозиторий содержит другие краткие руководства, такие как это сосредоточены на CDI-инъекциях Infinispan Cache и экземпляров JSR-107 Cache.

person Galder Zamarreño    schedule 03.08.2016
comment
способ использования JNDI для совместного использования менеджера кеша описан в руководстве infinispan (представлен в качестве примера) и используется другими разработчиками. Это один из способов совместного использования одного и того же cacheManager (большого объекта для сборки) среди всех войн, развернутых внутри сервера приложений. docs.jboss.org/infinispan/5.0/apidocs/ org/infinispan/manager/ После создания CacheManagers должен быть доступен любому компоненту, которому требуется кэш, через JNDI или через какой-либо другой механизм, например контейнер IoC. - person Alex; 03.08.2016
comment
Правильно, этот javadoc действительно нуждается в обновлении, поскольку JNDI действительно следует использовать для очень конкретных случаев использования. CDI — это гораздо более простая технология, которая обеспечивает жизненный цикл (создание/запуск/остановка/уничтожение) намного лучше, чем JNDI. - person Galder Zamarreño; 03.08.2016
comment
так что ваш ответ заключается в том, что JNDI не может высвободить все ресурсы mbean? - person Alex; 03.08.2016
comment
IDK, если я могу спросить здесь, но... Почему вы говорите, что мы не должны использовать infinispan, предоставляемый сервером? - person German Faller; 30.03.2019
comment
Использование сервером Infinispan может не всегда соответствовать тому, что вы хотите сделать. - person Galder Zamarreño; 09.04.2019