大家好,这里有个非常棘手的问题想请教,已经困扰了我好几天了,关于详细的代码请参见下方。
我的问题是:
我启动了2个Terracotta服务,多个ehcache实例同时连接到这2个TC服务,起到Cluster缓存的作用。当然,其中一个TC服务只是热备份的作用,为了便于理解,你认为只有一个TC服务就好了。
在Test1.java里面, 当我获取一个ehcache-tc.xml里面预先定义的cache并赋值给它的时候,我再启动Test2.java,这个时候在Test2.java里面,可以读取到这个值,说明cluster是工作的。
但是,当我在Test1.java动态创建一个新的cache时(没有在ehcache-tc.xml里面定义),Test2.java无法读取到该cache或者该cache里面的数据。我知道是因为Test1.java没有把这个新的cache放到cluster里面,请问如何用代码动态的放到cluster里面呢?
代码见下面:
2个Terracotta服务的配置文件:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<con:tc-config xmlns:con="http://www.terracotta.org/config">
<servers>
<server host="10.0.1.113" name="tc1">
<dso-port bind="0.0.0.0">9510</dso-port>
<jmx-port bind="0.0.0.0">9520</jmx-port>
<data>/Users/colky/java/terracotta/server-data1</data>
<logs>/Users/colky/java/terracotta/server-logs1</logs>
<statistics>/Users/colky/java/terracotta/cluster-statistics1</statistics>
<dso>
<persistence>
<mode>permanent-store</mode>
</persistence>
</dso>
</server>
<server host="10.0.1.113" name="tc2">
<dso-port bind="0.0.0.0">9610</dso-port>
<jmx-port bind="0.0.0.0">9620</jmx-port>
<data>/Users/colky/java/terracotta/server-data2</data>
<logs>/Users/colky/java/terracotta/server-logs2</logs>
<statistics>/Users/colky/java/terracotta/cluster-statistics2</statistics>
<dso>
<persistence>
<mode>permanent-store</mode>
</persistence>
</dso>
</server>
<!--If using more than one server, add an <ha> section.-->
<ha>
<mode>networked-active-passive</mode>
<networked-active-passive>
<election-time>5</election-time>
</networked-active-passive>
</ha>
</servers>
<clients>
<logs>/Users/colky/java/terracotta/client-logs</logs>
</clients>
<application>
<dso>
<instrumented-classes/>
</dso>
</application>
</con:tc-config>
配置好之后,就是启动这2个tc服务,当然你也可以启动一个。
在Java Project里面,配置ehcache-tc.xml:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd">
<terracottaConfig url="10.0.1.113:9510, 10.0.1.113:9610" />
<defaultCache maxElementsInMemory="100000" eternal="false" memoryStoreEvictionPolicy="LRU"
timeToIdleSeconds="100000" timeToLiveSeconds="100000" maxElementsOnDisk="0">
<terracotta clustered="true" coherent="true" valueMode="serialization"/>
</defaultCache>
<cache name="CACHE_TEST" maxElementsInMemory="100000" eternal="false" memoryStoreEvictionPolicy="LRU"
timeToIdleSeconds="100000" timeToLiveSeconds="100000" maxElementsOnDisk="0">
<terracotta clustered="true" coherent="true" valueMode="serialization"/>
</cache>
</ehcache>
测试代码:
Test1.java
Code:
package ehcache;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
public class Test1 {
public static void main(String[] args) {
CacheManager.create(Test1.class.getResource("/ehcache-tc.xml"));
//get a cache defined in ehcache xml
Cache cacheTest = CacheManager.getInstance().getCache("CACHE_TEST");
//define a new cache, how add into cluster?
Cache cacheNew = null;
if (!CacheManager.getInstance().cacheExists("CACHE_NEW")) {
//i tried multiple method to create a new cache and both cannot work in cluster
//method 1: create new one and add into cache manager.
cacheNew = new Cache("CACHE_NEW", 10000, MemoryStoreEvictionPolicy.LFU, false, null, true,
120, 120, false, 1000, null, null, 10000000, 30, true, true, "serialization", true);
CacheManager.getInstance().addCache(cacheNew);
//method 2: create new one via CacheManager
//CacheManager.getInstance().addCache("CACHE_NEW");
//method 3: get CACHE_TEST's configuration from ehcache-tc.xml and rename to CACHE_NEW, and create base on the configuration
//skip here, don't know how to write.
System.out.println("Created cache: CACHE_NEW");
} else {
cacheNew = CacheManager.getInstance().getCache("CACHE_NEW");
}
for (int i=0;i<=100;i++) {
cacheTest.put(new Element("test_key1", "value " + i));
System.out.println(cacheTest.get("test_key1")); // can got value here
cacheNew.put(new Element("new_key1", "value " + i));
System.out.println(cacheNew.get("new_key1")); // also can got value here
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
CacheManager.getInstance().shutdown();
}
}
Test2.java
Code:
package ehcache;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
public class Test2 {
public static void main(String[] args) {
CacheManager.create(Test2.class.getResource("/ehcache-tc.xml"));
//get a cache defined in ehcache xml
Cache cacheTest = CacheManager.getInstance().getCache("CACHE_TEST");
Cache cacheNew = CacheManager.getInstance().getCache("CACHE_NEW");
System.out.println("cacheNew is null: " + (cacheNew == null));
for (int i=0;i<=100;i++) {
System.out.println(cacheTest.get("test_key1")); // can got value here
// cannot got value here, because cacheNew is null
if (cacheNew != null)
System.out.println(cacheNew.get("new_key1"));
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
CacheManager.getInstance().shutdown();
}
}
测试方法:启动 test1.java,然后再启动Test2.java,你会发现当2个class读写CACHE_TEST这个cache的时候,都没有问题,但是当读写一个代码生成的新的cache的时候,test2.java就读取不到了,请教怎么样才能做到代码动态生成cache并cluster!?