3

I'm developing a web application distributed on multi nodes with java 8 and java ee7 on wildfly-11.0.0.Final, and i used infinispan cache for share data. This is the configuration of cache:

<cache-container name="mycache-container" default-cache="my-cache" jndi-name="infinispan/mycache-container">
    <transport lock-timeout="60000"/>
    <replicated-cache name="my-cache" jndi-name="infinispan/mycache-container/my-cache" mode="ASYNC">
        <locking isolation="READ_COMMITTED"/>
        <transaction locking="OPTIMISTIC" mode="NON_XA"/>
        <eviction strategy="NONE"/>
    </replicated-cache>
</cache-container>

And this is the configuration of jgroups subsystem used for replicated cache:

<subsystem xmlns="urn:jboss:domain:jgroups:5.0">
        <channels default="ee">
            <channel name="ee" stack="tcpping" cluster="ejb"/>
        </channels>
        <stacks>
            <stack name="tcpping">
                <transport type="TCP" socket-binding="jgroups-tcp"/>
                <protocol type="org.jgroups.protocols.TCPPING">
                    <property name="initial_hosts">
                        node1[7600], node2[7600]
                    </property>
                </protocol>
                <protocol type="MERGE3"/>
                <protocol type="FD_SOCK"/>
                <protocol type="FD_ALL"/>
                <protocol type="VERIFY_SUSPECT"/>
                <protocol type="pbcast.NAKACK2"/>
                <protocol type="UNICAST3"/>
                <protocol type="pbcast.STABLE"/>
                <protocol type="pbcast.GMS"/>
                <protocol type="MFC"/>
                <protocol type="FRAG2"/>
            </stack>
        </stacks>
    </subsystem>

On the application's startup i load all entity from database and put in the cache. If i inject cache through container in this way:

@Resource(lookup="java:jboss/infinispan/mycache-container") 
EmbeddedCacheManager container;

@PostConstruct
public void init(){
    Cache mycache = container.getCache();
}

the app start and load all objects in cache without problem, but in the other nodes these objects are not replicated also that jgroups cluster is created wihout errors. Instead if i inject cache directly in this way:

@Resource(lookup="java:jboss/infinispan/mycache-container/my-cache") 
Cache myCache;

the app in startup give me this error: "WFLYCTL0348: Timeout after [300] seconds waiting for service container stability. Operation will roll back. Step that first updated the service; and the server not start"

How should I use the cache to prevent timeout on startup and be able to replicate that objects on all nodes?

Thank you.

1 Answers1

3

The reason the 1st approach doesn't work as expected is because you've done nothing to insure that the requisite cache configuration is installed before your call to EmbeddedCacheManager.getCache().

To ensure the requisite cache configuration is installed, you can either:

  1. Inject the cache directly (as you've done in your 2nd approach)
  2. Add a dependency on the requisite cache configuration to your application, via @Resource or resource-ref.

I always recommend #1, as it is more intuitive, less verbose, and the cache lifecycle is handled by the container.

As to the cause of the "Timeout [...] waiting for container stability", I can't say for sure without seeing the code that loads objects into you cache as well as the relevant stack trace. Just a guess - are you sure you the transaction mode to be NON_XA? This means that cache operations are committed via a Synchronization to an active UserTransaction. This isn't a common requirement. If you're loading your cache in a @PostConstruct method, and aren't handling transactions correctly, this could prevent your component from starting (leading to a timeout waiting for container stability).

On an unrelated note, I would recommend using the non-deprecated TCPPING configuration. e.g.

<socket-discovery-protocol type="TCPPING" socket-bindings="node0 node1"/>

... where the socket-bindings reference configured outbound-socket-bindings. e.g.

<outbound-socket-binding name="node0">
    <remote-destination host="node0" port="7600"/>
</outbound-socket-binding>
<outbound-socket-binding name="node1">
    <remote-destination host="node1" port="7600"/>
</outbound-socket-binding>
Paul Ferraro
  • 326
  • 1
  • 3
  • Thanks paul, for your answer. I solved the startup problem and recovering the cache directly now I can replicate the data. I also had to change the transaction mode from NON_XA to NONE – Mario Vitale Jan 05 '18 at 08:21
  • @Paul, did you mean "I always recommend #2, as it is more intuitive, less verbose..." ? – Galder Zamarreño Jan 05 '18 at 11:18
  • To clarify, I recommend option #1, injecting a cache directly (i.e. 1 dependency); rather than option #2, injecting the cache manager and adding a second dependency on the requisite cache configuration. Using option #1, the cache lifecycle is handled by the container, whereas using option #2, the application must manage the cache lifecycle. Conainer managed lifecycle is very convenient, especially when the same managed cache is used by multiple applications. – Paul Ferraro Jan 06 '18 at 15:29
  • @Paul, i now inject the cache direcly, but the performance (r/w) of cache is more slowly than i inject from container. What can I do to increase performance? – Mario Vitale Jan 08 '18 at 08:46
  • Your observations are deceiving. The performance you saw when "inject[ing] from [the] container" would have returned a local cache (i.e. using infinispan's default settings) rather than the replicated cache you were expecting. A replicated cache is naturally much slower than a local cache (which is little more than a hash map). – Paul Ferraro Jan 13 '18 at 19:58