昨天写了个Coherence的小例子,使用了Oracle Enterprise Pack for Eclipse,直接用它创建了一个ADF项目,连带创建了JPA项目,在Configuration里添加了Coherence,这样就有了配套的jar包了。
Coherence利用多播自动组成集群,类可以不实现序列化接口,这是一个简单的例子:
public class Cat {
private String name;
private int age;
private String sex;
public Cat() {
super();
}
public Cat(String name, int age, String sex) {
super();
this.name = name;
this.age = age;
this.sex = sex;
}
服务类:
public class CatService {
public Cat getCat(String name){
NamedCache cache = CacheFactory.getCache("AnimalCache");
Cat cat = (Cat) cache.get(name);
if(cat==null){
long age = Math.round(Math.random() * 10)+5;
cat = new Cat(name,(int) age,"male");
cache.put(name, cat);
}
return cat;
}
}
测试:
public class CatServiceTest {
CatService catService=new CatService();
@Before
public void setUp() throws Exception {
CacheFactory.ensureCluster();
}
@After
public void tearDown() throws Exception {
CacheFactory.shutdown();
}
@Test
public void test() {
Cat tomCat=catService.getCat("tom");
Cat tomCatFromCache=catService.getCat("tom");
System.out.println(tomCat);
assertEquals(tomCat, tomCatFromCache);
}
}
Coherence推荐采用pof作为Serializer,这样不需要实现序列化接口,而且性能非常高,需要做以下几件事实现这个:
1 创建Serializer类:
public class CatSerializer implements PofSerializer {
@Override
public Object deserialize(PofReader pofReader) throws IOException {
String sName=pofReader.readString(0);
Cat cat=new Cat();
cat.setName(sName);
pofReader.registerIdentity(cat);
cat.setAge(pofReader.readInt(1));
cat.setSex(pofReader.readString(2));
pofReader.readRemainder();
return cat;
}
@Override
public void serialize(PofWriter pofWriter, Object object) throws IOException {
Cat cat=(Cat)object;
pofWriter.writeString(0,cat.getName());
pofWriter.writeInt(1, cat.getAge());
pofWriter.writeString(2, cat.getSex());
pofWriter.writeRemainder(null);
}
}
2 创建一个coherence-config文件,指定serializer,共有三个级别的指定,针对特定service,针对所有service,针对jvm,下面是针对所有service。
<cache-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.oracle.com/coherence/coherence-cache-config"
xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-cache-config http://xmlns.oracle.com/coherence/coherence-cache-config/1.1/coherence-cache-config.xsd">
<!-- The defaults element defines factory-wide default settings. -->
<defaults>
<!-- Note: This element defines the default serializer for all services
defined within this cache configuration descriptor. Valid values include
full serializer definitions, as well as named references to serializers defined
within the "serializers" element of the operational configuration. Example
values include: java, pof. Default value is java. -->
<!--<serializer system-property="tangosol.coherence.serializer" />-->
<serializer>
<instance>
<class-name>com.tangosol.io.pof.ConfigurablePofContext</class-name>
<init-params>
<init-param>
<param-type>String</param-type>
<param-value>custom-pof-config.xml</param-value>
</init-param>
</init-params>
</instance>
</serializer>
3 编写custom-pof-config.xml,注册serializer:
<?xml version="1.0"?>
<pof-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.oracle.com/coherence/coherence-pof-config"
xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-pof-config http://xmlns.oracle.com/coherence/coherence-pof-config/1.1/coherence-pof-config.xsd">
<user-type-list>
<!-- include all "standard" Coherence POF user types -->
<include>coherence-pof-config.xml</include>
<user-type>
<type-id>1001</type-id>
<class-name>org.jport.coherence.demo.Cat</class-name>
<serializer>
<class-name>org.jport.coherence.demo.CatSerializer</class-name>
</serializer>
</user-type>
</user-type-list>
</pof-config>
4 指定这个自定义的coherence-config.xml,在jvm启动参数里:
-Dtangosol.coherence.cacheconfig=C:\workspace\AdfprjModel\src\custom-coherence-cache-config.xml
由于我是用JUnit进行测试,因此就是把这个写在run junit的configuration里了。
如果属性是引用了其他的类也没问题:
public class Cat {
private String name;
private int age;
private String sex;
private Owner owner;
public class Owner {
private String name;
private String phoneNumber;
public Owner(String name, String phoneNumber) {
super();
this.name = name;
this.phoneNumber = phoneNumber;
}
创建Owner的Serializer:
public class OwnerSerializer implements PofSerializer {
@Override
public Object deserialize(PofReader pofReader) throws IOException {
String sName=pofReader.readString(0);
Owner owner=new Owner();
owner.setName(sName);
pofReader.registerIdentity(owner);
owner.setPhoneNumber(pofReader.readString(1));
pofReader.readRemainder();
return owner;
}
@Override
public void serialize(PofWriter pofWriter, Object object) throws IOException {
Owner owner=(Owner)object;
pofWriter.writeString(0,owner.getName());
pofWriter.writeString(1, owner.getPhoneNumber());
pofWriter.writeRemainder(null);
}
}
修改Cat的Serializer:
public class CatSerializer implements PofSerializer {
@Override
public Object deserialize(PofReader pofReader) throws IOException {
String sName=pofReader.readString(0);
Cat cat=new Cat();
cat.setName(sName);
pofReader.registerIdentity(cat);
cat.setAge(pofReader.readInt(1));
cat.setSex(pofReader.readString(2));
cat.setOwner((Owner) pofReader.readObject(3));
pofReader.readRemainder();
return cat;
}
@Override
public void serialize(PofWriter pofWriter, Object object) throws IOException {
Cat cat=(Cat)object;
pofWriter.writeString(0,cat.getName());
pofWriter.writeInt(1, cat.getAge());
pofWriter.writeString(2, cat.getSex());
pofWriter.writeObject(3, cat.getOwner());
pofWriter.writeRemainder(null);
}
}
然后在pof配置中新增该类型:
<user-type>
<type-id>1002</type-id>
<class-name>org.jport.coherence.demo.Owner</class-name>
<serializer>
<class-name>org.jport.coherence.demo.OwnerSerializer</class-name>
</serializer>
</user-type>
引用集合类:
public class Cat {
private String name;
private int age;
private String sex;
private Owner owner;
private List<Cat> childrenCats;
修改Cat服务类:
public Cat getCat(String name){
NamedCache cache = CacheFactory.getCache("AnimalCache");
Cat cat = (Cat) cache.get(name);
if(cat==null){
int age =(int) Math.round(Math.random() * 10)+5;
cat = new Cat(name, age,"male");
Owner owner = new Owner("sslaowan","1212554525");
cat.setOwner(owner);
List<Cat> childrenCats=new ArrayList<Cat>();
Cat child1 = new Cat("tt",age-3,"female");
child1.setOwner(owner);
Cat child2 = new Cat("mm",age-3,"female");
child2.setOwner(owner);
childrenCats.add(child1);
childrenCats.add(child2);
cat.setChildrenCats(childrenCats);
cache.put(name, cat);
}
return cat;
}
修改Serializer:
public class CatSerializer implements PofSerializer {
@Override
public Object deserialize(PofReader pofReader) throws IOException {
String sName=pofReader.readString(0);
Cat cat=new Cat();
cat.setName(sName);
pofReader.registerIdentity(cat);
cat.setAge(pofReader.readInt(1));
cat.setSex(pofReader.readString(2));
cat.setOwner((Owner) pofReader.readObject(3));
cat.setChildrenCats((List<Cat>) pofReader.readCollection(4, new ArrayList<Cat>()));
pofReader.readRemainder();
return cat;
}
@Override
public void serialize(PofWriter pofWriter, Object object) throws IOException {
Cat cat=(Cat)object;
pofWriter.writeString(0,cat.getName());
pofWriter.writeInt(1, cat.getAge());
pofWriter.writeString(2, cat.getSex());
pofWriter.writeObject(3, cat.getOwner());
pofWriter.writeCollection(4, cat.getChildrenCats(), Cat.class);
pofWriter.writeRemainder(null);
}
}
测试结果如下:
Cat [name=tom, age=6, sex=male, owner=Owner [name=sslaowan, phoneNumber=1212554525],
childrenCats=[Cat [name=tt, age=3, sex=female, owner=Owner [name=sslaowan, phoneNumber=1212554525], childrenCats=null],
Cat [name=mm, age=3, sex=female, owner=Owner [name=sslaowan, phoneNumber=1212554525], childrenCats=null]]]
运行多个节点加入集群,可以让JUnit测试
Group{Address=224.3.7.0, Port=37000, TTL=4}
MasterMemberSet(
ThisMember=Member(Id=4, Timestamp=2012-05-23 17:44:27.749, Address=192.168.56.1:8094, MachineId=14169, Location=site:,machine:wanxing-PC,process:12444, Role=EclipseJdtRemoteTestRunner)
OldestMember=Member(Id=1, Timestamp=2012-05-23 17:35:23.01, Address=192.168.56.1:8088, MachineId=14169, Location=site:,machine:wanxing-PC,process:14536, Role=EclipseJdtRemoteTestRunner)
ActualMemberSet=MemberSet(Size=4
Member(Id=1, Timestamp=2012-05-23 17:35:23.01, Address=192.168.56.1:8088, MachineId=14169, Location=site:,machine:wanxing-PC,process:14536, Role=EclipseJdtRemoteTestRunner)
Member(Id=2, Timestamp=2012-05-23 17:35:28.781, Address=192.168.56.1:8090, MachineId=14169, Location=site:,machine:wanxing-PC,process:13692, Role=EclipseJdtRemoteTestRunner)
Member(Id=3, Timestamp=2012-05-23 17:36:06.641, Address=192.168.56.1:8092, MachineId=14169, Location=site:,machine:wanxing-PC,process:14964, Role=EclipseJdtRemoteTestRunner)
Member(Id=4, Timestamp=2012-05-23 17:44:27.749, Address=192.168.56.1:8094, MachineId=14169, Location=site:,machine:wanxing-PC,process:12444, Role=EclipseJdtRemoteTestRunner)
)
MemberId|ServiceVersion|ServiceJoined|MemberState
1|3.7.1|2012-05-23 17:35:23.01|JOINED,
2|3.7.1|2012-05-23 17:35:28.781|JOINED,
3|3.7.1|2012-05-23 17:36:06.641|JOINED,
4|3.7.1|2012-05-23 17:44:27.769|JOINED
RecycleMillis=1200000
RecycleSet=MemberSet(Size=0
)
)
TcpRing{Connections=[3]}
IpMonitor{AddressListSize=0}
关于pof的更多内容看这个: