Replicated infinispan cache with Wildfly 11

2019-07-23 22:03发布

问题:

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:

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>