使用Memcached作为全网站分布式缓存
来源:互联网 发布:手机fc2最新域名设置 编辑:程序博客网 时间:2024/05/16 15:40
使用Memcached作为全网站分布式缓存,大体思路就是:
首先搭建一些Memcached服务器,作为全网站的分布式缓存服务器。当Controller层调用以get*开头的service查询方法时,首先进入配置的切面对象,执行环绕通知方法,查看Memcached中是否已经有了此查询方法执行后的结果,如果有数据,则直接返回Controller,如果没有数据,就返回service层执行查询方法,并且把执行结果放入到Memcached中缓存起来。
当Controller层调用以add*,delete*,update*开头的service方法时,因为这些这些方法的执行会导致数据库数据变更,因此要清理受到影响的那部分缓存的数据,以免造成数据延迟,即也要进入在spring中配置的切面对象,执行后置通知方法,清空受影响的部分缓存数据。
其中有个关键点,是把service查询的数据结果放入Memcached时的K怎么设置,为了保证唯一性,可以设定K生成规则如下:
K=包名+类名+方法名+参数(可以多个),其中,如果参数是javabean的话,要先转为json串,再与前面的包名+类名+方法名进行拼接。
其中包名+类名比如:com.core.serice.product.ProductServiceImpl.productList
①首先要在Linux服务器上搭建Memcache服务器,这个可以查看Memcached官方文档
②在java项目中加入memcache-xx.jar,又分为两个包:
com.danga.MemCached与
net.spy.memcached
因为danga包有连接池,更稳定,因此此次使用的是danga包的Memcached
③Spring引入Memcached.xml,在其中进行连接池,切面对象和aop配置,这样就能保证所有对系统所有以get*,add*,delete*,update*开头的service方法生效:
<?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:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"><!-- Memcached 配置 --><bean id="memCachedClient" class="com.danga.MemCached.MemCachedClient"><constructor-arg><value>sockIOPool</value></constructor-arg></bean><!-- Memcached连接池 --><bean id="sockIOPool" class="com.danga.MemCached.SockIOPool" factory-method="getInstance" init-method="initialize" destroy-method="shutDown"><constructor-arg><value>sockIOPool</value></constructor-arg><property name="servers"><list><!-- 此处可以配置多台安装了Memcached的服务器,Memcached自带路由功能,我们不需要知道数据具体存到了哪个数据库 --><value>192.168.200.149:11211</value></list></property><property name="weights"><list><value>1</value></list></property></bean><!-- 配置切面对象,expiry是切面类里加的时间参数 --><bean id="cacheInterceptor" class="com.common.web.aop.CacheInterceptor"><property name="expiry" value="4200000"/></bean><!-- Spring Aop 配置 get*配置环绕通知 ,update*、add*、delete*配置后置通知--><aop:config><!-- 面 --><aop:aspect ref="cacheInterceptor"><!-- 点 --><aop:around method="doAround" pointcut="execution(* com.core.service.*.*.get*(..))"/><!-- 变更 --><aop:after method="doAfter" pointcut="execution(* com.core.service.*.*.update*(..))"/><aop:after method="doAfter" pointcut="execution(* com.core.service.*.*.add*(..))"/><aop:after method="doAfter" pointcut="execution(* com.core.service.*.*.delete*(..))"/></aop:aspect></aop:config></beans>
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = "classpath:application-context.xml")public class MemcachedTest{@Autowiredprivate MemCachedClient memCachedClient;@Testpublic void testAdd() throws Exception {Student student = new Student();student.setName("哈哈");//存数据//memCachedClient.set("aa",student);//取数据Object object = memCachedClient.get("aa");System.out.println(object);}}
/** * 缓存Memcached中数据的切面对象 */public class CacheInterceptor {@Autowiredprivate MemCachedClient memCachedClient;//缓存时间,单位是秒private int expiry = 60*60*24*3;//配置环绕通知方法,get*会执行,环绕通知使用ProceedingJoinPoint,其中包含了请求的一些参数,能够获取要执行的包名,类型,方法名,参数之类的数据public Object doAround(ProceedingJoinPoint pjp) throws Throwable{//去Memcached中查看有没有此get方法查找的数据 包名+ 类名 + 方法名 + 参数(多个)String cacheKey = getCacheKey(pjp);System.out.println(cacheKey);//如果Memcached连接不上if(memCachedClient.stats().isEmpty()){System.out.println("Memcached服务器可能不存在或是连接不上");//pjp.proceed()此处就是放开拦截,执行service方法查询return pjp.proceed();}//如果以前没有缓存过此get方法查询的数据if(null == memCachedClient.get(cacheKey)){//回ServiceObject proceed = pjp.proceed();//吧数据缓存到Memcached中一份memCachedClient.set(cacheKey, proceed,expiry);}return memCachedClient.get(cacheKey);}//add*,update*,delete*后置通知,由于数据库数据变更,因此要清理受到影响的那部分缓存的数据。后置通知使用的是JoinPoint,没有了.proceed()方法public void doAfter(JoinPoint jp){//获取包名+类名 String packageName = jp.getTarget().getClass().getName();//以包名+类名开始的缓存数据都清理掉//Memcached中获取所有key的方法比较复杂,getKeySet(memCachedClient)也是从网上找的Map<String, Object> keySet = MemCachedUtil.getKeySet(memCachedClient);Set<Entry<String, Object>> entrySet = keySet.entrySet();//遍历清除for(Entry<String, Object> entry : entrySet){if(entry.getKey().startsWith(packageName)){memCachedClient.delete(entry.getKey());}}}//使用包名+类名+方法名+参数(多个)的生成策略生成Memcached保存需要的Keypublic String getCacheKey(ProceedingJoinPoint pjp){StringBuilder key = new StringBuilder();//获取包名+类名,比如com.core.serice.product.ProductServiceImpl.productListString packageName = pjp.getTarget().getClass().getName();key.append(packageName);//获取方法名String methodName = pjp.getSignature().getName();key.append(".").append(methodName);//获取参数(可能是多个)Object[] args = pjp.getArgs();//因为参数可能是javabean,所以此处要转为json串才能进行拼接生成keyObjectMapper om = new ObjectMapper();om.setSerializationInclusion(Inclusion.NON_NULL);//遍历参数,转json串for(Object arg : args){//流StringWriter str = new StringWriter(); //对象转Json,写入流中try {om.writeValue(str, arg);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}//参数key.append(".").append(str);}return key.toString();}public void setExpiry(int expiry) {this.expiry = expiry;}}
⑥接下来实现Memcached 集群的高可用(HA)架构可参考下面的博客:
http://blog.csdn.net/liu251890347/article/details/38414247
- 使用Memcached作为全网站分布式缓存
- hibernate-memcached--在Hibernate中使用Memcached作为一个二级分布式缓存
- hibernate-memcached--在Hibernate中使用Memcached作为一个二级分布式缓存
- hibernate-memcached--在Hibernate中使用Memcached作为一个二级分布式缓存
- hibernate-memcached--在Hibernate中使用Memcached作为一个二级分布式缓存
- 分布式缓存memcached安装使用资料收集
- 分布式缓存Memcached之Java使用篇
- 分布式缓存系统memcached安装和使用
- .net下使用memcached分布式缓存数据
- window版分布式缓存Memcached使用攻略
- Net MVC4使用Memcached实现分布式缓存
- 分布式缓存 - memCached Voldemort
- Memcached-----分布式缓存
- 分布式缓存---Memcached 入门
- 分布式缓存Memcached
- 分布式缓存---Memcached 入门
- 分布式缓存---Memcached 入门
- 分布式缓存系统 Memcached
- 获得GPUImage处理后的UIImage
- maven-compiler-plugin配置
- 汇编:将十进制或十六进制数转化成二进制数输出
- sencha touch 项目的样式不起作用了
- 访问javascript对象的属性和方法
- 使用Memcached作为全网站分布式缓存
- 说说Android 两种为自定义组件添加属性的使用方法和区别
- linux实时监控或查看系统资源使用情况的工具——TOP
- 关于 Fatal error: ‘SpringBoard/SpringBoard.h’ file not found
- 针对JCO运行在window2003 R2 32bit
- 快速提高Android开发效率的工具
- weblogic虚拟目录映射
- 【指导】iOS代码静态检查 -- clang format (+ git pre-commit hook + jenkins)
- 时间不够用,不知道去哪了