Ehcache on Jboss Replication in One Split Server

牧云@^-^@ 提交于 2019-12-12 04:36:01

问题


First, let me describe the environment we have.

Currently, we are deploying a project on a JBoss AS 7 application server in a remote computer somewhere. As of now, this JBoss has been clustered into 4 nodes. 2 servers split into two sub-server groups:

  • Server One
    • Server One - 1
    • Server One - 2
  • Server Two
    • Server Two - 1
    • Server Two - 2

NOTE: Deploying the app in JBoss with these active effectively makes it available to all of them. It's like deploying the same app to all four of them.

That said, we are trying to implement an Ehcache enabled project here.Ehcache is defined inside a very simple web project which populates a cache and displays it on a page.

My index page for testing this:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
    <h1>Hello World!</h1>

    &lt;&lt; <a href="display">Display</a> | <a href="populate">Populate</a> | <a href="remove">Remove</a> &gt;&gt;
    <br/>

    Session ID: <c:out value="<%= session.getId() %>" /><br/>
    Session is New: <c:out value="<%= session.isNew() %>" /><br/>
<br/><br/>
    Value in "key":
    <c:if test="${storedValue != null}">
        <c:out value="${storedValue}" />

    </c:if> <c:if test="${storedValue == null}">
        null

    </c:if> 
</body>
</html>

My application context only has this line:

<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">   
     <property name="configLocation" value="classpath:/ehcache.xml" />    
</bean>

ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
    updateCheck="false">

    <defaultCache eternal="true" maxElementsInMemory="100"
        overflowToDisk="false" />

    <cache name="customer" maxElementsInMemory="10" eternal="true"
        overflowToDisk="false">
        <cacheEventListenerFactory
            class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
            properties="asynchronousReplicationIntervalMillis=500 " />
        <bootstrapCacheLoaderFactory
            class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory" />
    </cache>

    <cacheManagerPeerProviderFactory
        class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
        properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.4, 
                    multicastGroupPort=47500, timeToLive=32" />

    <cacheManagerPeerListenerFactory
        class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
        properties="port=40001, socketTimeoutMillis=2000" />


</ehcache>

My controller currently looks like this:

@Controller
@RequestMapping("/")
public class IndexController {

    private static final String VALUE = "value";
    private static final String KEY = "key";
    private static final String CUSTOMER = "customer";
    @Autowired
    private CacheManager cacheManager;

    @RequestMapping("/")
    public String defaultMode(Model model) {
        Cache cache = cacheManager.getCache(CUSTOMER);
        getKeyFromCache(model, cache, KEY);

        return "index";
    }

    @RequestMapping("/populate")
    public String populateMode(Model model) {

        Cache cache = cacheManager.getCache(CUSTOMER);
        cache.put(new Element(KEY, VALUE));
        getKeyFromCache(model, cache, KEY);

        return "index";
    }

    @RequestMapping("/display")
    public String displayMode(Model model) {
        Cache cache = cacheManager.getCache(CUSTOMER);
        getKeyFromCache(model, cache, KEY);

        return "index";
    }

    @RequestMapping("/remove")
    public String removeMode(Model model) {

        Cache cache = cacheManager.getCache(CUSTOMER);
        cache.remove(KEY);
        getKeyFromCache(model, cache, KEY);

        return "index";
    }

    private void getKeyFromCache(Model model, Cache cache, String key) {

        String objValue;
        if (cache.get(key) != null) {
            objValue = cache.get(key).getObjectValue().toString();
        } else {
            objValue = null;
        }

        model.addAttribute("storedValue", objValue);
    }

}

Now. What's the problem? It's actually the replication. We are using the RMI replication of Ehcache in an attempt to replicate the contents of the cache in one server division to another.

I have read in some answers that all you need to do is change the ports of the listeners for each instance you deploy to be unique for them to find each other. But that won't work here, seeing as i only effectively deploy just one application and it appears in all of these servers.

How do I know which server the cache is on? I printed out the session. After testing my controller, and going to it's "populate" page. It only stores the data in one sub-server. Which means if one gets it, the others don't.

The main question now is, can ehcache handle replication if it's technically one app and copies of it exist in just one JBoss server group? It basically shuffles to the same app every time you refresh. Can it handle a replication in one instance of a server which splits it?

来源:https://stackoverflow.com/questions/13394427/ehcache-on-jboss-replication-in-one-split-server

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!