Memcached笔记——(二)XMemcached&Spring集成

博客分类:

ServerArchitecture/Distributed

Java/Cache

Spring

MemcachedjavaXMemcached

今天研究Memcached的Java的Client,使用XMemcached1.3.5,做个简单的测试,并介绍如何与Spring集成。

一、MemcachedClient简要介绍

MemcachedClient目前有3种:

MemcachedClientforJava

SpyMemcached

XMemcached

这三种Client一直存在各种争议:

MemcachedClientforJava比SpyMemcached更稳定、更早、更广泛;

SpyMemcached比MemcachedClientforJava更高效;

XMemcached比SpyMemcache并发效果更好。

用数据来说话,参考官方性能对比:

MemcachedClientforJava:https://github.com/gwhalin/Memcached-Java-Client/wiki/PERFORMANCE

XMemcached:http://xmemcached.googlecode.com/svn/trunk/benchmark/benchmark.html

二、XMemcached特性

XMemcached特性:

高性能

支持完整的memcached文本协议,二进制协议。

支持JMX,可以通过MBean调整性能参数、动态添加/移除server、查看统计等。

支持客户端统计

支持memcached节点的动态增减。

支持memcached分布:余数分布和一致性哈希分布。

更多的性能调整选项。

此外,XMemcached更容易与Spring集成。而且,属于中国原创!

三、XMemcached简单实现

MemcachedClientBuilder是MemcachedClient核心接口,用来控制Client的构建(build()方法)和关闭(shutdown()方法)。

XMemcachedClientBuilder一般通过构造方法配置地址列表,通常还要配置权重,代码如下:

Java代码收藏代码

publicXMemcachedClientBuilder(List<InetSocketAddress>addressList){

if(addressList!=null){

for(InetSocketAddressaddr:addressList){

this.addressMap.put(addr,null);

}

}

}

publicXMemcachedClientBuilder(List<InetSocketAddress>addressList,

int[]weights){

if(addressList!=null){

for(InetSocketAddressaddr:addressList){

this.addressMap.put(addr,null);

}

}

this.weights=weights;

}

不过这哥们如果用this()可以省点代码,还有给加点注释吧!

此外,还需要设置连接池大小,使用二进制协议/文本协议等。

通过build()方法获得MemcachedClient

然后就可以通过Memcached进行set、get、replace、delete等Memcached操作了!

上代码:

Java代码收藏代码

importstaticjunit.framework.Assert.*;

importjava.io.IOException;

importjava.util.concurrent.TimeoutException;

importnet.rubyeye.xmemcached.MemcachedClient;

importnet.rubyeye.xmemcached.MemcachedClientBuilder;

importnet.rubyeye.xmemcached.XMemcachedClientBuilder;

importnet.rubyeye.xmemcached.command.BinaryCommandFactory;

importnet.rubyeye.xmemcached.exception.MemcachedException;

importnet.rubyeye.xmemcached.utils.AddrUtil;

importorg.junit.Test;

publicclassMemcachedClientTest{

@Test

publicvoidtest(){

MemcachedClientBuilderbuilder=newXMemcachedClientBuilder(

AddrUtil.getAddresses("10.11.155.26:1121110.11.155.41:1121110.10.76.31:1121110.10.76.35:11211"),

newint[]{1,1,1,1});

//设置连接池大小,即客户端个数

builder.setConnectionPoolSize(50);

//宕机报警

builder.setFailureMode(true);

//使用二进制文件

builder.setCommandFactory(newBinaryCommandFactory());

MemcachedClientmemcachedClient=null;

try{

memcachedClient=builder.build();

try{

//设置/获取

memcachedClient.set("zlex",36000,"set/get");

assertEquals("set/get",memcachedClient.get("zlex"));

//替换

memcachedClient.replace("zlex",36000,"replace");

assertEquals("replace",memcachedClient.get("zlex"));

//移除

memcachedClient.delete("zlex");

assertNull(memcachedClient.get("zlex"));

}catch(TimeoutExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}catch(InterruptedExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}catch(MemcachedExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}

}catch(IOExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}finally{

if(memcachedClient!=null){

try{

memcachedClient.shutdown();

}catch(IOExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}

}

}

}

}

四、XMemcached与Spring集成

XMemcached与Spring集成可以参考http://code.google.com/p/xmemcached/wiki/Spring_Integration,这里只说最常用的方法。

memcached.properties做基本配置:

Properties代码收藏代码

#连接池大小即客户端个数

memcached.connectionPoolSize=50

memcached.failureMode=true

#server1

memcached.server1.host=10.11.155.26

memcached.server1.port=11211

memcached.server1.weight=4

#server2

memcached.server2.host=10.11.155.41

memcached.server2.port=11211

memcached.server2.weight=3

#server3

memcached.server3.host=10.10.76.31

memcached.server3.port=11211

memcached.server3.weight=2

#server4

memcached.server4.host=10.10.76.35

memcached.server4.port=11211

memcached.server4.weight=1

XML配置文件:

Xml代码收藏代码

<?xmlversion="1.0"encoding="UTF-8"?>

<beans

xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:p="http://www.springframework.org/schema/p"

xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd">

<!--http://code.google.com/p/xmemcached/wiki/Spring_Integration-->

<context:property-placeholderlocation="memcached.properties"/>

<bean

id="memcachedClientBuilder"

class="net.rubyeye.xmemcached.XMemcachedClientBuilder"

p:connectionPoolSize="${memcached.connectionPoolSize}"

p:failureMode="${memcached.failureMode}">

<!--XMemcachedClientBuilderhavetwoarguments.Firstisserverlist,and

secondisweightsarray.-->

<constructor-arg>

<list>

<beanclass="java.net.InetSocketAddress">

<constructor-arg>

<value>${memcached.server1.host}</value>

</constructor-arg>

<constructor-arg>

<value>${memcached.server1.port}</value>

</constructor-arg>

</bean>

<beanclass="java.net.InetSocketAddress">

<constructor-arg>

<value>${memcached.server2.host}</value>

</constructor-arg>

<constructor-arg>

<value>${memcached.server2.port}</value>

</constructor-arg>

</bean>

<beanclass="java.net.InetSocketAddress">

<constructor-arg>

<value>${memcached.server3.host}</value>

</constructor-arg>

<constructor-arg>

<value>${memcached.server3.port}</value>

</constructor-arg>

</bean>

<beanclass="java.net.InetSocketAddress">

<constructor-arg>

<value>${memcached.server4.host}</value>

</constructor-arg>

<constructor-arg>

<value>${memcached.server4.port}</value>

</constructor-arg>

</bean>

</list>

</constructor-arg>

<constructor-arg>

<list>

<value>${memcached.server1.weight}</value>

<value>${memcached.server2.weight}</value>

<value>${memcached.server3.weight}</value>

<value>${memcached.server4.weight}</value>

</list>

</constructor-arg>

<propertyname="commandFactory">

<beanclass="net.rubyeye.xmemcached.command.TextCommandFactory"/>

</property>

<propertyname="sessionLocator">

<beanclass="net.rubyeye.xmemcached.impl.KetamaMemcachedSessionLocator"/>

</property>

<propertyname="transcoder">

<beanclass="net.rubyeye.xmemcached.transcoders.SerializingTranscoder"/>

</property>

</bean>

<!--Usefactorybeantobuildmemcachedclient-->

<bean

id="memcachedClient"

factory-bean="memcachedClientBuilder"

factory-method="build"

destroy-method="shutdown"/>

</beans>

这里的memcachedClientBuilder节点完成MemcachedClientBuilder,然后通过memcachedClient节点配置factory-method,调用MemcachedClientBuilder的build()方法产生MemcachedClient,并配置destroy-method进行关闭。

不过我还是疑惑,这里的异常由谁来处理?Spring容器吗?或者需要另一个代理Bean包装一下?

有了Spring容器支持,我们不需要在代码中进行配置,也不需要重复调用build()跟shutdown()方法,这些操作交给Spring来完成。

代码如下:

Java代码收藏代码

importstaticjunit.framework.Assert.*;

importjava.util.concurrent.TimeoutException;

importnet.rubyeye.xmemcached.MemcachedClient;

importnet.rubyeye.xmemcached.exception.MemcachedException;

importorg.junit.Before;

importorg.junit.Test;

importorg.springframework.context.ApplicationContext;

importorg.springframework.context.support.ClassPathXmlApplicationContext;

publicclassMemcachedSpringTest{

privateApplicationContextapp;

privateMemcachedClientmemcachedClient;

@Before

publicvoidinit(){

app=newClassPathXmlApplicationContext("applicationContext.xml");

memcachedClient=(MemcachedClient)app.getBean("memcachedClient");

}

@Test

publicvoidtest(){

try{

//设置/获取

memcachedClient.set("zlex",36000,"set/get");

assertEquals("set/get",memcachedClient.get("zlex"));

//替换

memcachedClient.replace("zlex",36000,"replace");

assertEquals("replace",memcachedClient.get("zlex"));

//移除

memcachedClient.delete("zlex");

assertNull(memcachedClient.get("zlex"));

}catch(TimeoutExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}catch(InterruptedExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}catch(MemcachedExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}

}

}

相关推荐