一、Memcached Client简要介绍 
Memcached Client目前有3种: 
这三种Client一直存在各种争议: 
- Memcached Client for Java 比 SpyMemcached更稳定、更早、更广泛;
 - SpyMemcached 比 Memcached Client for Java更高效;
 - XMemcached 比 SpyMemcache并发效果更好。
 
用数据来说话,参考官方性能对比: 
Memcached Client for Java: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一般通过构造方法配置地址列表,通常还要配置权重,代码如下:
- public XMemcachedClientBuilder(List<InetSocketAddress> addressList) {
 - if (addressList != null) {
 - for (InetSocketAddress addr : addressList) {
 - this.addressMap.put(addr, null);
 - }
 - }
 - }
 - public XMemcachedClientBuilder(List<InetSocketAddress> addressList,
 - int[] weights) {
 - if (addressList != null) {
 - for (InetSocketAddress addr : addressList) {
 - this.addressMap.put(addr, null);
 - }
 - }
 - this.weights = weights;
 - }
 
不过这哥们如果用this()可以省点代码,
 还有给加点注释吧!
 此外,还需要设置连接池大小,使用二进制协议/文本协议等。
通过build()方法获得MemcachedClient
然后就可以通过Memcached进行set、get、replace、delete等Memcached操作了!
 上代码:
- import static junit.framework.Assert.*;
 - import java.io.IOException;
 - import java.util.concurrent.TimeoutException;
 - import net.rubyeye.xmemcached.MemcachedClient;
 - import net.rubyeye.xmemcached.MemcachedClientBuilder;
 - import net.rubyeye.xmemcached.XMemcachedClientBuilder;
 - import net.rubyeye.xmemcached.command.BinaryCommandFactory;
 - import net.rubyeye.xmemcached.exception.MemcachedException;
 - import net.rubyeye.xmemcached.utils.AddrUtil;
 - import org.junit.Test;
 - public class MemcachedClientTest {
 - @Test
 - public void test() {
 - MemcachedClientBuilder builder = new XMemcachedClientBuilder(
 - AddrUtil.getAddresses("10.11.155.26:11211 10.11.155.41:11211 10.10.76.31:11211 10.10.76.35:11211"),
 - new int[] { 1, 1, 1, 1 });
 - // 设置连接池大小,即客户端个数
 - builder.setConnectionPoolSize(50);
 - // 宕机报警
 - builder.setFailureMode(true);
 - // 使用二进制文件
 - builder.setCommandFactory(new BinaryCommandFactory());
 - MemcachedClient memcachedClient = 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 (TimeoutException e) {
 - // TODO Auto-generated catch block
 - e.printStackTrace();
 - } catch (InterruptedException e) {
 - // TODO Auto-generated catch block
 - e.printStackTrace();
 - } catch (MemcachedException e) {
 - // TODO Auto-generated catch block
 - e.printStackTrace();
 - }
 - } catch (IOException e) {
 - // TODO Auto-generated catch block
 - e.printStackTrace();
 - } finally {
 - if (memcachedClient != null) {
 - try {
 - memcachedClient.shutdown();
 - } catch (IOException e) {
 - // TODO Auto-generated catch block
 - e.printStackTrace();
 - }
 - }
 - }
 - }
 - }
 
四、XMemcached与Spring集成 
XMemcached与Spring集成可以参考http://code.google.com/p/xmemcached/wiki/Spring_Integration,这里只说最常用的方法。 
memcached.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 version="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/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 - http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
 - <!-- http://code.google.com/p/xmemcached/wiki/Spring_Integration -->
 - <context:property-placeholder location="memcached.properties" />
 - <bean
 - id="memcachedClientBuilder"
 - class="net.rubyeye.xmemcached.XMemcachedClientBuilder"
 - p:connectionPoolSize="${memcached.connectionPoolSize}"
 - p:failureMode="${memcached.failureMode}">
 - <!-- XMemcachedClientBuilder have two arguments.First is server list,and
 - second is weights array. -->
 - <constructor-arg>
 - <list>
 - <bean class="java.net.InetSocketAddress">
 - <constructor-arg>
 - <value>${memcached.server1.host}</value>
 - </constructor-arg>
 - <constructor-arg>
 - <value>${memcached.server1.port}</value>
 - </constructor-arg>
 - </bean>
 - <bean class="java.net.InetSocketAddress">
 - <constructor-arg>
 - <value>${memcached.server2.host}</value>
 - </constructor-arg>
 - <constructor-arg>
 - <value>${memcached.server2.port}</value>
 - </constructor-arg>
 - </bean>
 - <bean class="java.net.InetSocketAddress">
 - <constructor-arg>
 - <value>${memcached.server3.host}</value>
 - </constructor-arg>
 - <constructor-arg>
 - <value>${memcached.server3.port}</value>
 - </constructor-arg>
 - </bean>
 - <bean class="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>
 - <property name="commandFactory">
 - <bean class="net.rubyeye.xmemcached.command.TextCommandFactory" />
 - </property>
 - <property name="sessionLocator">
 - <bean class="net.rubyeye.xmemcached.impl.KetamaMemcachedSessionLocator" />
 - </property>
 - <property name="transcoder">
 - <bean class="net.rubyeye.xmemcached.transcoders.SerializingTranscoder" />
 - </property>
 - </bean>
 - <!-- Use factory bean to build memcached client -->
 - <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来完成。
代码如下:
- import static junit.framework.Assert.*;
 - import java.util.concurrent.TimeoutException;
 - import net.rubyeye.xmemcached.MemcachedClient;
 - import net.rubyeye.xmemcached.exception.MemcachedException;
 - import org.junit.Before;
 - import org.junit.Test;
 - import org.springframework.context.ApplicationContext;
 - import org.springframework.context.support.ClassPathXmlApplicationContext;
 - public class MemcachedSpringTest {
 - private ApplicationContext app;
 - private MemcachedClient memcachedClient;
 - @Before
 - public void init() {
 - app = new ClassPathXmlApplicationContext("applicationContext.xml");
 - memcachedClient = (MemcachedClient) app.getBean("memcachedClient");
 - }
 - @Test
 - public void test() {
 - 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 (TimeoutException e) {
 - // TODO Auto-generated catch block
 - e.printStackTrace();
 - } catch (InterruptedException e) {
 - // TODO Auto-generated catch block
 - e.printStackTrace();
 - } catch (MemcachedException e) {
 - // TODO Auto-generated catch block
 - e.printStackTrace();
 - }
 - }
 - }
 
转载地址:http://snowolf.iteye.com/blog/1471805
来源:https://www.cnblogs.com/peijie-tech/p/3849432.html




