设为首页 收藏本站
查看: 785|回复: 0

[经验分享] 利用Attribute与PIAB构建支持memcached功能的数据访问层

[复制链接]

尚未签到

发表于 2015-8-31 13:00:11 | 显示全部楼层 |阅读模式
  之前一直在做memcached的研究,并通过memcached做了很多性能优化,把许多执行频繁的语句 通过cache缓存起来,但做的很多都是service层的复杂数据缓存,数据访问层基本没有碰过。如果要动数据访问层,假设按照最普通的编程思路,说不 定我们改造数据访问层,可能会产生以下这样的代码:


class UserDAC
{
public User GetUser(int id)
{
//从缓存中取
User user = memcached.get(“user_”+id)

If(user == null)
{
//没取到从缓存中取
user = db.LoadFromKey(“user_table”,id);

//存入缓存中
if(user != null)
memcached.add(“user_”+id,user);
}

//返回结果
return user;
}
}  其实这个函数的核心逻辑是 user = db.LoadFromKey(…),如果能把cache的存取方法给剥离出去,就能达到解耦的目的。而实现这一目的的方式就是用AOP的办法来实现。
  AOP的实现方式有很多,不使用语言特性的话可以利用装饰者模式来实现类似AOP的效果。我这为了图方便,推荐大家使用企业库里的Policy Injection Application Block(PIAB),而且这块实现的功能也比装饰者模式强大很多。
  基本的思路是这样的:
  1.    让UserDAC类继承MarshalByRefObject:这个基类是支持远程处理的对象基类,学过远程对象调用的同志们都知道,他会生成代理类来支持实际对象的调用。PIAB实现的办法就是在这个代理类上做了手脚。
  2.    用特别的方法来构造UserDAC对象:如果用UserDAC dac = new UserDAC(),那这个还没动手脚的对象是实现不了AOP的,需要通过特殊的方式来构造对象。具体方式如下:


UserDAC dac = PolicyInjection.Create<UserDAC>();  这样拿到的对象就可以让我们为所欲为了,哇哈哈哈&#8230;.不好意思&#8230;有点兴奋了&#8230;
  3.    设置拦截policy:这里可以通过企业库自带的配置程序来生成config,其中拦截方法有两种方式:
  a)    可以通过正则表达式匹配来选择拦截哪些方法,不过这种办法比较麻烦,因为都是写在config里,到时候config长的恐怖。
  b)    我这边使用的是attribute来实现拦截,这样默认情况下只要拦截所有的方法就行,我通过attribute的判断来决定是否拦截。
  这边attribute定义如下:


[AttributeUsage(AttributeTargets.Method)]
public class CacheAttribute : Attribute
{
public string CacheName
{   get; set ;  }

public string Operation
{   get; set;   }

public CacheAttribute(string cacheName, string operation)
{ &#8230;  }

}  如果某个方法上加了这个attribute,我们就认为他是被拦截方法,执行cache过程。其中的operation是个枚举,代表cache的get,set,update,remove等操作,默认是get&set操作。
  那我们的UserDAC可以定义这样了:


class UserDAC : MarshalByRefObject
{
[Cache(&#8220;user&#8221;, &#8221;get&#8221;)]
public User GetUser([CachePara]int id)
{
return db.LoadFromKey(&#8220;user_table&#8221;,id);
}

[Cache(&#8220;user&#8221;, &#8220;update&#8221;)]
public bool Update([CachePara]int id, User user)
{
db.update(user);
}
}  大家可以看到通过PIAB和attribute的双重方法,支持缓存的数据访问层的代码变得和没有缓存支持的代码差不多了,无非是多了几个attribute,不需要再去写那么多冗余的memached的get,set,remove操作了。
其中大家可以看到有个[CachPara]的attribute,这个是用来标明cache的key的,如果cachename相同,cachepara对应的值也相同,那我们就认为是一个对象。
  最后我们还有一件事情要做,就是要自己写个自定义的handler来处理拦截的事件,由于篇幅限制,我就写下伪代码,为大家理清思路为主:


[ConfigurationElementType(typeof(CustomCallHandlerData))]
class CacheHandler : ICallHandler
{
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
//通过反射找方法是否有CacheAtrribute
CacheAttribute att = getAtt(&#8220;cacheattribute&#8221;, input);

//没有,执行原方法并返回结果
If(att == null) return getNext();

//根据不同的操作,来做不同的事情
switch(att.operation)
{
//读取操作
case get&set:
//先读memcached
object cacheobj = memcache.get(cachename+cachpara);
//有的话直接返回
if(cacheobj != null)
return cacheobj;
else
{
//没有就执行原方法,并把值存入缓存
object returnobj = getnext();
memcached.add(cachename+cachepara,returnobj);
return returnobj;
}
//更新操作
case update:
//清除缓存,避免数据不同步
memcache.update(cachename+cachepara)
return getnext();
}

}
}  通过这样一个简单方便的改造,我们就可以很容易构建带memcached功能的数据访问层。而且即使你不想用缓存,直接读数据库,那也很简单,用new UserDAC()对象来调用方法即可,使用相当灵活。
  呵呵,可能写的有点乱,如果大家有不理解的可以回复本文,我会及时回答的。
  
  原文地址:http://it.dianping.com/using_attribute_and_piab_to_hybrid_memcached_and_data_access_layer.htm

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-106827-1-1.html 上篇帖子: 利用Spring AOP 更新memcached 缓存策略的实现(二) 下篇帖子: Velocity, 微软的Memcached?!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表