XMemcached与spring的集成实例
来源:互联网 发布:linux文件夹 编辑:程序博客网 时间:2024/06/08 03:06
1.Memcached Client简要介绍
Memcached Client目前有3种:
1.Memcached Client for Java 2.SpyMemcached 3.XMemcached
这三种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
2.XMemcached特性
高性能;支持完整的memcached文本协议,二进制协议;支持JMX,可以通过MBean调整性能参数、动态添加/移除server、查看统计等;支持客户端统计;支持memcached节点的动态增减;支持memcached分布:余数分布和一致性哈希分布;更多的性能调整选项。
3.XMemcached简单实现
MemcachedClientBuilder是MemcachedClient核心接口,用来控制Client的构建(build()方法)和关闭(shutdown()方法)。 通过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(
"192.168.1.110:11211 192.168.1.111:11211"
),
new
int
[] {
1
,
1
});
// 设置连接池大小,即客户端个数
builder.setConnectionPoolSize(
50
);
// 宕机报警
builder.setFailureMode(
true
);
// 使用二进制文件
builder.setCommandFactory(
new
BinaryCommandFactory());
// 使用一致性哈希算法(Consistent Hash Strategy)
builder.setSessionLocator(
new
KetamaMemcachedSessionLocator());
// 使用序列化传输编码
builder.setTranscoder(
new
SerializingTranscoder());
// 进行数据压缩,大于1KB时进行压缩
builder.getTranscoder().setCompressionThreshold(
1024
);
MemcachedClient memcachedClient =
null
;
try
{
memcachedClient = builder.build();
try
{
// 设置/获取
memcachedClient.set(
"aa"
,
36000
,
"set/get"
);
assertEquals(
"set/get"
, memcachedClient.get(
"aa"
));
// 替换
memcachedClient.replace(
"aa"
,
36000
,
"replace"
);
assertEquals(
"replace"
, memcachedClient.get(
"aa"
));
// 移除
memcachedClient.delete(
"aa"
);
assertNull(memcachedClient.get(
"aa"
));
}
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();
}
}
}
}
}
4.XMemcached与Spring集成 更新数据后原来对应的类模块键过期策略,对缓存键存在数据库中策略的代替
spring-xmemcached.xml注释的部分是可以配置多个memcached服务器的
<!-- 引入Memcached客户端开始--> <bean name="memcachedClientBuilder" class="net.rubyeye.xmemcached.XMemcachedClientBuilder"> <constructor-arg> <list> <bean class="java.net.InetSocketAddress"> <constructor-arg> <value>192.168.100.102</value> </constructor-arg> <constructor-arg> <value>11211</value> </constructor-arg> </bean> <!-- <bean class="java.net.InetSocketAddress"> <constructor-arg> <value>localhost</value> </constructor-arg> <constructor-arg> <value>12001</value> </constructor-arg> </bean> --> </list> </constructor-arg> <constructor-arg> <list> <value>1</value> <!-- <value>2</value> --> </list> </constructor-arg> <property name="connectionPoolSize" value="2"></property> <property name="commandFactory"> <bean class="net.rubyeye.xmemcached.command.TextCommandFactory"></bean> </property> <property name="sessionLocator"> <bean class="net.rubyeye.xmemcached.impl.KetamaMemcachedSessionLocator"></bean> </property> <property name="transcoder"> <bean class="net.rubyeye.xmemcached.transcoders.SerializingTranscoder" /> </property> </bean> <bean name="memcachedClient" factory-bean="memcachedClientBuilder" factory-method="build" destroy-method="shutdown" /> <!-- 引入Memcached客户端结束 -->
<!-- get cache拦截器 --><bean id="methodCacheInterceptor" class="com.jing.memcached.interceptor.XMemcachedMethodCacheInterceptor"><property name="memcachedClient"><ref local="memcachedClient" /></property></bean><bean id="methodCachePointCut"class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"><property name="advice"><ref local="methodCacheInterceptor" /></property><property name="patterns"><list><value>com.jing.*.getAllUser</value> <value>com.jing.*.update.*</value> <value>com.jing.*.add.*</value></list></property></bean> <!--一个ProxyFactoryBean类只能指定一个代理目标。BeanNameAutoProxyCreator类自动代理,可以代理多个目标 --><bean id="myService" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"><property name="beanNames" value="*ServiceImpl"/> <!--配置文件中可以使用@Autowired注解实例化的类 --> <property name="interceptorNames"><list><value>methodCachePointCut</value></list></property></bean>
拦截器配置:
package com.jing.memcached.interceptor;import java.lang.reflect.Method;import net.rubyeye.xmemcached.MemcachedClient;import org.aopalliance.intercept.MethodInterceptor;import org.aopalliance.intercept.MethodInvocation;import org.springframework.beans.factory.InitializingBean;import org.springframework.util.Assert;import com.jing.memcached.annotation.CacheAdd;import com.jing.memcached.annotation.CacheRemove;/** * @author 静国强 * @date 2015-9-11 * @desc 配置MemCachedClient拦截器 */public class XMemcachedMethodCacheInterceptor implements MethodInterceptor,InitializingBean {private MemcachedClient memcachedClient;public void setMemcachedClient(MemcachedClient memcachedClient) {this.memcachedClient = memcachedClient;}public void afterPropertiesSet() throws Exception {Assert.notNull(memcachedClient,"A cache is required. Use setCache(Cache) to provide one.");}public Object invoke(MethodInvocation invocation) throws Throwable { Method[] methods = invocation.getThis().getClass().getDeclaredMethods(); String targetName = invocation.getThis().getClass().getName();Method method = invocation.getMethod(); //这种方法不能取到它的注解String methodName = method.getName();Object[] arguments = invocation.getArguments();Object result= null;Object object = null;//定义版本号 String prefixValue = null; //通过方法名获取每个方法模块的版本号 if(null != memcachedClient.get(targetName)) { prefixValue = memcachedClient.get(targetName).toString(); } else { prefixValue = CacheVersion.getVersion(); memcachedClient.set(targetName,60*60*24*30, prefixValue); }String cacheKey = getCacheKey(targetName, methodName, arguments) + prefixValue;System.out.println(">>>>>>>>>进入拦截:方法"+methodName+">>>>>>cacheKey:"+cacheKey);for(Method m:methods){ //循环方法,找匹配的方法进行执行 用m才能取到它的注解 System.out.println("aa循环:"+m.getName()+" "+m.isAnnotationPresent(CacheAdd.class) +m.isAnnotationPresent(CacheRemove.class)); if(m.getName().equals(methodName)){ if(m.isAnnotationPresent(CacheAdd.class)){ System.out.println(">>>>>>>>>添加缓存分支");//添加缓存synchronized (this) {object = memcachedClient.get(cacheKey);if (object == null) {// 调用实际的方法result = invocation.proceed();System.out.println(">>>>>>>>>走数据库得到结果集为:"+result);memcachedClient.add(cacheKey,60*60*24 ,result ); //单位:秒 }else{System.out.println(">>>>>>>>>走缓存_得到结果集为:"+object);}}result = memcachedClient.get(cacheKey);}else if(m.isAnnotationPresent(CacheRemove.class)){ System.out.println(">>>>>>>>>删除缓存分支"); //执行正常操作result = invocation.proceed(); //修改后,版本号 。以前的版本号组成的cacheKey就查询不到了 慢慢过期销毁 String version =CacheVersion.getVersion(); memcachedClient.replace(targetName,60*60*24, version); System.out.println("更新"+targetName+"版本号为:"+version);}else{System.out.println(">>>>>>>>>没有缓存操作分支");result = invocation.proceed();} break;//找到这个方法就退出循环 } }return result; }private String getCacheKey(String targetName, String methodName,Object[] arguments) {StringBuffer sb = new StringBuffer();sb.append(targetName).append(".").append(methodName);if ((arguments != null) && (arguments.length != 0)) {for (int i = 0; i < arguments.length; i++) {sb.append(".").append(arguments[i]);}}return sb.toString();}}
生成版本号
package com.jing.memcached.interceptor;import java.util.UUID;public class CacheVersion {public static String getVersion(){UUID uuid = UUID.randomUUID();return uuid.toString().toUpperCase(); }}
- XMemcached与spring的集成实例
- XMemcached与Spring集成
- Xmemcached与Spring 3.0的集成
- Xmemcached与Spring 3.0的集成
- Memcached xmemcached与 Spring集成
- xmemcached的集成spring配置
- XMemcached&Spring集成
- XMemcached&Spring集成
- XMemcached&Spring集成
- spring-xmemcached 集成
- XMemcached&Spring集成
- xmemcached主要用法及与Spring集成--总结
- memcached-java客户端xmemcached使用总结 & 与Spring 集成
- xmemcached主要用法及与Spring集成--总结
- xmemcached主要用法及与Spring集成--总结
- XMemcached与Spring
- XMemcached和spring缓存框架集成
- Memcached-学习(二)XMemcached&Spring集成
- HDOJ 5448 Marisa’s Cake
- [RFID]IC卡克隆(一)Proxmark3简介
- 纯CSS3制作皮卡丘动画壁纸
- python编程:使用opencv按一定间隔截取视频帧
- vector C语言详细用法的分析
- XMemcached与spring的集成实例
- IOS 获取,如电量,CPU,型号
- ajax实现二级联动_读取的是xml文件
- 响应式网页设计的9条基本原则
- C++ Primer Plus(第六版)--学习杂记(第一第二章)
- Unity物理引擎:Rigidbody简介
- 几个重要的jvm参数配置及建议
- Android XML动画资源文件详细讲解(下)
- 肺纤维化