网站导航网学 原创论文 原创专题 网站设计 最新系统 原创论文 论文降重 发表论文 论文发表 UI设计定制 论文答辩PPT格式排版 期刊发表 论文专题
返回网学首页
网学原创论文
最新论文 推荐专题 热门论文 论文专题
当前位置: 网学 > 设计资源 > .Net编程 > 正文

网站架构之缓存应用(3)实现篇

论文降重修改服务、格式排版等 获取论文 论文降重及排版 论文发表 相关服务

 这篇来讲如何利用memcached实现一级缓存,以及如何让一级缓存组件支持在企业库,memcached或者其它第三方实施方案之间的切换。memcached本人并没有太多经验,如果文中有说的不对的地方,还希望批评指出,且文中关于memcached的代码大多来自网络。

     创建memcached实现类MemcachedWebCacheProvider,由它来继承缓存提供者接口IWebCacheProvider,主里memcached客户端我采用.NET memcached client library ,这个类库很久没有更新这过了,没有和java版同步,有部分功能目前没有实现。
     1:初始化memcached服务,这段初始化代码在程序中保证执行一次就够,一般可以放在gloabl文件中,或者是设置一个静态变量来存储服务的状态。

  1. private void Setup() 
  2.         { 
  3.             String serverlist = { "127.0.0.1:11211" }; 
  4.             this._pool = SockIOPool.GetInstance("default"); 
  5.             this._pool.SetServers(serverlist); //设置服务器列 
  6.             //各服务器之间负载均衡的设置 
  7.             this._pool.SetWeights(new int { 1 }); 
  8.             //socket pool设置 
  9.             this._pool.InitConnections = 5; //初始化时创建的连接数 
  10.             this._pool.MinConnections = 5; //最小连接数 
  11.             this._pool.MaxConnections = 250; //最大连接数 
  12.             //连接的最大空闲时间,下面设置为6个小时(单位ms),超过这个设置时间,连接会被释放掉 
  13.             this._pool.MaxIdle = 1000 * 60 * 60 * 6; 
  14.             //通讯的超时时间,下面设置为3秒(单位ms),.NET版本没有实现 
  15.             this._pool.SocketTimeout = 1000 * 3; 
  16.             //socket连接的超时时间,下面设置表示连接不超时,即一直保持连接状态 
  17.             this._pool.SocketConnectTimeout = 0; 
  18.             this._pool.Nagle = false//是否对TCP/IP通讯使用Nalgle算法,.NET版本没有实现 
  19.             //维护线程的间隔激活时间,下面设置为60秒(单位s),设置为0表示不启用维护线程 
  20.             this._pool.MaintenanceSleep = 60; 
  21.             //socket单次任务的最大时间,超过这个时间socket会被强行中断掉(当前任务失败) 
  22.             this._pool.MaxBusy = 1000 * 10; 
  23.             this._pool.Initialize(); 
  24.         } 

  2:获取一个memcached客户端。

  1. private MemcachedClient GetClient() 
  2.         { 
  3.             MemcachedClient client = new MemcachedClient(); 
  4.             client.PoolName = "default"
  5.             return client; 
  6.         } 

3:根据memcached提供的功能实现IWebCacheProvider,代码就不贴了,大家可以自己去试试。

        到此我们就利用memcached实现了一级缓存,由于.NET memcached client library 实现了分布式,我们只需要在多台服务器上安装上memcached服务,在初始化memcached代码中增加了服务器相关配置即可。String serverlist = { "127.0.0.1:11211" };

        如何让一级缓存组件支持多实现方案之间的切换。
        MyWebCacheServiceClient:客户端缓存组件实例,它来完成一级缓存与二级缓存之间的联系,以及根据配置文件来选择一级缓存的实施方案。
        第一:CacheServiceMode,根据它就可以决定缓存是只缓存二级缓存还是两级都缓存。
                 1:LocalCacheOnlyMode,只启用web server上的二级缓存。
                 2:BufferedLCacheServerMode,即启用web server上的二级缓存也启用cache server上的缓存。
                 3:Off,关闭缓存功能。
        第二:IWebCacheProvider service = this .GetPrimaryCacheProvider(hashKey);方式决定了一级缓存的实施方案。

  1. /// <summary> 
  2.         /// 获取一级缓存 
  3.         /// </summary> 
  4.         /// <param name="hashKey"></param> 
  5.         /// <param name="configFilePath"></param> 
  6.         /// <returns></returns> 
  7.         private IWebCacheProvider GetPrimaryCacheProvider(uint hashKey) 
  8.         { 
  9.             IWebCacheProvider provider = null
  10.             string cacheType = WebConfig.ChannelConfig["CacheType"].ToString().ToLower(); 
  11.             switch (cacheType) 
  12.             { 
  13.                 case "memcached"
  14.                     provider = WebCacheProviderFactory.GetMemcachedWebCacheProvider(configFilePath); 
  15.                     break
  16.                 case "entlib"
  17.                     provider = servicePool.GetServiceClient(hashKey) as IWebCacheProvider; 
  18.                     break
  19.             } 
  20.             
  21.             return provider; 
  22.         } 

 插入缓存的逻辑:原理就是根据配置文件中的CacheMode来完成缓存级别的判定以及一级缓存的方案。

  1. public void Insert(string key, object value, string region, string subRegion, CacheItemConfig cacheItemConfig) 
  2.         { 
  3.             if (string.IsNullOrEmpty(key) || value == null
  4.                 return
  5.             //关闭模式,不使用缓存 
  6.             if (Options.CacheServiceMode == ECacheServiceMode.Off) 
  7.             { 
  8.                 return
  9.             } 
  10.             else if (Options.CacheServiceMode == ECacheServiceMode.BufferedLCacheServerMode 
  11.                 || Options.CacheServiceMode == ECacheServiceMode.LocalAndCacheServerAndSql 
  12.                 || Options.CacheServiceMode == ECacheServiceMode.LocalCacheOnlyMode) 
  13.             {//使用带缓冲的模式 
  14.                 if (Options.BufferType == ECacheDependencyType.SlidingTime) 
  15.                 { 
  16.                     SecondaryCacheProvider.Insert(key, value, region, subRegion, MyCacheItemPriority.Normal, Options.BufferSlidingTime); 
  17.                 } 
  18.                 else if (Options.BufferType == ECacheDependencyType.AbsoluteTime) 
  19.                 { 
  20.                     SecondaryCacheProvider.Insert(key, value, region, subRegion, MyCacheItemPriority.Normal, Options.BufferAbsoluteTime); 
  21.                 } 
  22.  
  23.                 if (Options.CacheServiceMode == ECacheServiceMode.LocalCacheOnlyMode) 
  24.                 {//只使用本地缓存 
  25.                     return
  26.                 } 
  27.             } 
  28.  
  29.             checkKey(key); 
  30.             uint hashKey = hash(key); 
  31.  
  32.             try 
  33.             { 
  34.                 if (Options.CacheServiceMode == ECacheServiceMode.CacheServerMode 
  35.                     || Options.CacheServiceMode == ECacheServiceMode.BufferedLCacheServerMode 
  36.                     || Options.CacheServiceMode == ECacheServiceMode.CacheServerAndSql 
  37.                     || Options.CacheServiceMode == ECacheServiceMode.LocalAndCacheServerAndSql) 
  38.                 {//CacheServer模式使用Cache服务器保存Cache                                       
  39.                     IWebCacheProvider service = this .GetPrimaryCacheProvider(hashKey); 
  40.                     byte byteValue = SerializationHelper.SaveToBinaryBytes(value); 
  41.                     var cachePriority = ModelConverter.ToRefClass(cacheItemConfig.CachePriority); 
  42.                     if (cacheItemConfig.CacheType == ECacheDependencyType.AbsoluteTime) 
  43.                     { 
  44.                         AbsoluteTimeCacheDependency absTime = new AbsoluteTimeCacheDependency(); 
  45.                         absTime.AbsoluteTime = DateTime.Now.AddMinutes(cacheItemConfig.CacheTimeMinutes); 
  46.                         service.Insert(key, byteValue, region, subRegion, cachePriority, absTime); 
  47.                     } 
  48.                     else if (cacheItemConfig.CacheType == ECacheDependencyType.SlidingTime) 
  49.                     { 
  50.                         SlidingTimeCacheDependency slTime = new SlidingTimeCacheDependency(); 
  51.                         slTime.SlidingTime = new TimeSpan(0, cacheItemConfig.CacheTimeMinutes, 0); 
  52.                         service.Insert(key, byteValue, region, subRegion, cachePriority, slTime); 
  53.                     } 
  54.                 } 
  55.             } 
  56.             catch (Exception ex) 
  57.             {//出现异常,保存到数据库中 
  58.                 servicePool.ReplaceServiceClient(hashKey); 
  59.                 this.SendLogEmail(ex); 
  60.             } 
  61.             
  62.  
  63.         } 

   客户端调用代码:为了调用方便,创建一个CacheHelper来帮助完成:

  1. public class CacheHelper 
  2.     { 
  3.         /// <summary> 
  4.         /// 主分区 
  5.         /// </summary> 
  6.         public const string REGION = "MyBlog"
  7.         /// <summary> 
  8.         /// 子分区 
  9.         /// </summary> 
  10.         public const string SUB_REGION = "default"
  11.         public const string BlogListConfigKey = "BlogListConfigKey"
  12.         #region 页面间数据传递 
  13.         /// <summary> 
  14.         /// 新增页面间传递数据到WebCache 
  15.         /// </summary> 
  16.         /// <returns>返回PageKeyID,用于页面间传递的键值</returns> 
  17.         public static string InsertPageParams(string configKey, object obj,string pageKey) 
  18.         { 
  19.             string result = null
  20.  
  21.             MyWebCacheServiceClient cacheClient = CacheClientFactory.GetWebCacheServiceClient(REGION, SUB_REGION, configKey); 
  22.             cacheClient.Insert( 
  23.                 MyWebCacheServiceClient.BuildKey(configKey,pageKey), 
  24.                 obj, 
  25.                 REGION, 
  26.                 SUB_REGION); 
  27.  
  28.             return result; 
  29.         } 
  30.         /// <summary> 
  31.         /// 从Cache里获取页面传递Cache 
  32.         /// </summary> 
  33.         /// <param name="key">FlightCacheKey里的常量</param> 
  34.         /// <param name="pageKeyID">页面传递的键值</param> 
  35.         public static object GetPageParams(string configKey, string pageKey) 
  36.         { 
  37.             object result = null
  38.             MyWebCacheServiceClient cacheClient = CacheClientFactory.GetWebCacheServiceClient(REGION, 
  39.                 SUB_REGION, configKey); 
  40.             result = cacheClient.Get( 
  41.                 MyWebCacheServiceClient.BuildKey(configKey, pageKey), 
  42.                 REGION, 
  43.                 SUB_REGION); 
  44.  
  45.             return result; 
  46.  
  47.         } 
  48.         #endregion 
  49.     } 

 

两级缓存类结构图:

        以上代码贴出来看起来有点乱,这里贴出网站两级缓存类结构图:

          

设为首页 | 加入收藏 | 网学首页 | 原创论文 | 计算机原创
版权所有 网学网 [Myeducs.cn] 您电脑的分辨率是 像素
Copyright 2008-2020 myeducs.Cn www.myeducs.Cn All Rights Reserved 湘ICP备09003080号 常年法律顾问:王律师