• asp.net_缓存管理


    转自:http://www.cnblogs.com/mysweet/archive/2012/06/05/2536372.html

    缓存是性能优化一个非常重要的模块,几乎计算机哪里都会用到缓存,我们的网站缓存也是非常重要的一块,缓存给网站带来太大的性能提高,在asp.net中的Cache,同样有各种缓存依赖,文件缓存依赖,数据库缓存依赖等等,我们的缓存管理就成了一个很重要的问题,当我们的网站小的时候,我们采用asp.net内置的Cache就可以了,但是如果我们的网站进一步扩展,单独分布式缓存服务器的时候,我们采用Memcached的时候,我们又不得不大量去修改我们的代码,这就是我之前写死缓存的问题,如下图:

    201204241516421820

    这里配置缓存,如果,现在把asp.net缓存改为Memcached的时候,我们就坑爹了!

    因此,很多人就开始抱怨了,改改改!

    做网站就是改改改!

    呵呵!

    这就是一个非常重要的问题,程序员的工作似乎都在开发,修改代码中进行,而往往总是抱怨似乎没什么技术含量,天天做重复性的工作!

    这就是oo的开始,这时候就需要慢慢开始学习软件工程和面向对象,

    以前的层次,学习这些东西,一般也就是停留在理论层面上,软件工程,面向对象,总被人强调有用,但是总说不出为什么有用!

    一旦一个软件,网站做大,就难得多得多,考虑的东西也深得多得多!这就是软件更需要大局观,需要考虑全局,考虑复用,考虑架构!

    软件理论,很多人感觉很虚很虚,我刚开始也是这么感觉的,但是一旦你熟练了程序员的工作,写代码写CRUD写多了就容易出现瓶颈,感觉似乎软件都是增删改查和复杂的业务,各种技术浅尝则止,感觉无非如此,无非如此,还不如去学硬件方面的,呵呵!

    而这却离软件的思想越离越远,于是乎,出现了大量的精通asp.net,精通asp.net mvc,精通wpf,Silverlight,精通一大堆的人,无非也就是能写点增删改查,这也能叫做精通..........能不能自己写框架,写架构?看博客园那些技术牛人的代码就是一种享受,他们的代码,几乎隔一段时间都会发现技术的演变,重构.这就是造诣!

    于是更多的人开始不淡定,我敬佩博客园那么多专研同一种技术动不动就是好多年的牛人.

    话题扯远了!

    最近看了基本关于这方面的书,感触挺深的!

    我们的缓存这时候更应该抽象出来,形成一种组件,以适应日后分布式缓存,而且也方便调用.

    在DBO数据库连接类设计中,曾经采用工厂模式的方式以适应多种数据库的设计,

    image

    我们的缓存也可以设计成复用设计,支持多种缓存模式,

    这时候,看了一下.net应用架构设计原则,模式与实践,

    感觉那种缓存模式蛮好的,我也尝试着做了部分修改.

    image

    ICacheStorage就是通用缓存接口,

       1:  using System;
       2:  using System.Collections.Generic;
       3:  using System.Linq;
       4:  using System.Text;
       5:   
       6:  namespace CacheStorage
       7:  {
       8:      /// <summary>
       9:      /// 缓存接口
      10:      /// </summary>
      11:     public interface ICacheStorage
      12:      {
      13:          #region 缓存操作
      14:          /// <summary>
      15:          /// 添加缓存
      16:          /// </summary>
      17:          /// <param name="key"></param>
      18:          /// <param name="value"></param>
      19:          void Insert(string key, object value);
      20:          /// <summary>
      21:          /// 添加缓存(默认滑动时间为20分钟)
      22:          /// </summary>
      23:          /// <param name="key">key</param>
      24:          /// <param name="value">value</param>
      25:          /// <param name="expiration">绝对过期时间</param>
      26:          void Insert(string key, object value, DateTime expiration);
      27:          /// <summary>
      28:          /// 添加缓存
      29:          /// </summary>
      30:          /// <param name="key">key</param>
      31:          /// <param name="value">value</param>
      32:          /// <param name="expiration">过期时间</param>
      33:          void Insert(string key, object value, TimeSpan expiration);
      34:          /// <summary>
      35:          /// 获得key对应的value
      36:          /// </summary>
      37:          /// <param name="key"></param>
      38:          /// <returns></returns>
      39:          object Get(string key);
      40:          /// <summary>
      41:          /// 根据key删除缓存
      42:          /// </summary>
      43:          /// <param name="key"></param>
      44:          void Remove(string key);
      45:          /// <summary>
      46:          /// 缓存是否存在key的value
      47:          /// </summary>
      48:          /// <param name="key">key</param>
      49:          /// <returns></returns>
      50:          bool Exist(string key);
      51:          /// <summary>
      52:          /// 获取所有的缓存key
      53:          /// </summary>
      54:          /// <returns></returns>
      55:          List<string> GetCacheKeys();
      56:          /// <summary>
      57:          /// 清空缓存
      58:          /// </summary>
      59:          void Flush();
      60:          
      61:          #endregion
      62:      }
      63:    
      64:  }
    默认的asp.net缓存
       1:  using System;
       2:  using System.Collections.Generic;
       3:  using System.Linq;
       4:  using System.Text;
       5:  using System.Web;
       6:  using System.Web.Caching;
       7:  using System.Collections;
       8:  namespace CacheStorage
       9:  {
      10:      /// <summary>
      11:      /// 默认的asp.net中Cache
      12:      /// </summary>
      13:       class DefaultCacheAdapter : ICacheStorage
      14:      {
      15:          /// <summary>
      16:          /// 当前请求上下文
      17:          /// </summary>
      18:          private static HttpContext context = null;
      19:          /// <summary>
      20:          /// 构造函数
      21:          /// </summary>
      22:          static DefaultCacheAdapter()
      23:          {
      24:              context = HttpContext.Current;
      25:          }
      26:          #region ICacheStorage 成员
      27:          /// <summary>
      28:          /// 添加缓存
      29:          /// </summary>
      30:          /// <param name="key">key</param>
      31:          /// <param name="value">value</param>
      32:          public void Insert(string key, object value)
      33:          {
      34:              context.Cache.Insert(key, value);
      35:          }
      36:          /// <summary>
      37:          /// 添加缓存(默认滑动时间为20分钟)
      38:          /// </summary>
      39:          /// <param name="key">key</param>
      40:          /// <param name="value">value</param>
      41:          /// <param name="expiration">绝对过期时间</param>
      42:          public void Insert(string key, object value, DateTime expiration)
      43:          {
      44:              context.Cache.Insert(key, value, null, expiration, TimeSpan.FromMinutes(20), CacheItemPriority.Normal, null);
      45:          }
      46:          /// <summary>
      47:          /// 添加缓存
      48:          /// </summary>
      49:          /// <param name="key">key</param>
      50:          /// <param name="value">value</param>
      51:          /// <param name="expiration">过期时间</param>
      52:          public void Insert(string key, object value, TimeSpan expiration)
      53:          {
      54:              context.Cache.Insert(key, value, null, DateTime.MaxValue, expiration, CacheItemPriority.Normal, null);
      55:   
      56:          }
      57:          /// <summary>
      58:          /// 获取当前缓存中key的值
      59:          /// </summary>
      60:          /// <param name="key"></param>
      61:          /// <returns></returns>
      62:          public object Get(string key)
      63:          {
      64:              return context.Cache[key];
      65:   
      66:          }
      67:          /// <summary>
      68:          /// 删除当前key的value值
      69:          /// </summary>
      70:          /// <param name="key"></param>
      71:          public void Remove(string key)
      72:          {
      73:              if (Exist(key))
      74:                  context.Cache.Remove(key);
      75:          }
      76:          /// <summary>
      77:          /// 缓存是否存在key的value
      78:          /// </summary>
      79:          /// <param name="key">key</param>
      80:          /// <returns></returns>
      81:          public bool Exist(string key)
      82:          {
      83:              if (context.Cache[key] == null)
      84:                  return false;
      85:              else
      86:                  return true;
      87:          }
      88:          /// <summary>
      89:          /// 获取所有的缓存key
      90:          /// </summary>
      91:          /// <returns></returns>
      92:          public List<string> GetCacheKeys()
      93:          {
      94:              List<string> keys = new List<string>();
      95:              IDictionaryEnumerator ide = context.Cache.GetEnumerator();
      96:              while (ide.MoveNext())
      97:              {
      98:                  keys.Add(ide.Key.ToString());
      99:              }
     100:              return keys;
     101:          }
     102:          /// <summary>
     103:          /// 清空缓存
     104:          /// </summary>
     105:          public void Flush()
     106:          {
     107:              foreach (string s in GetCacheKeys())
     108:              {
     109:                  Remove(s);
     110:              }
     111:          }
     112:          #endregion
     113:      }
     114:  }
    分布式Memcached
       1:  using System;
       2:  using System.Collections.Generic;
       3:  using System.Linq;
       4:  using System.Text;
       5:  using Enyim.Caching;
       6:  using Enyim.Caching.Memcached;
       7:   
       8:  namespace CacheStorage
       9:  {
      10:      /// <summary>
      11:      /// 分布式Memcached缓存
      12:      /// </summary>
      13:      class MemcachedCache : ICacheStorage
      14:      {
      15:          /// <summary>
      16:          /// 分布式缓存客户端Cache
      17:          /// </summary>
      18:          private MemcachedClient Cache;
      19:          public MemcachedCache()
      20:          {
      21:              Cache = new MemcachedClient();
      22:              List<string> keys = new List<string>();
      23:              Cache.Store(StoreMode.Add, "keys", keys);
      24:          }
      25:          #region ICacheStorage 成员
      26:          /// <summary>
      27:          /// 插入缓存
      28:          /// </summary>
      29:          /// <param name="key">key</param>
      30:          /// <param name="value">value</param>
      31:          public void Insert(string key, object value)
      32:          {
      33:              Cache.Store(StoreMode.Set, key, value);
      34:   
      35:          }
      36:          /// <summary>
      37:          /// 插入缓存
      38:          /// </summary>
      39:          /// <param name="key">key</param>
      40:          /// <param name="value">value</param>
      41:          /// <param name="expiration">绝对过期时间</param>
      42:          public void Insert(string key, object value, DateTime expiration)
      43:          {
      44:              Cache.Store(StoreMode.Set, key, value, expiration);
      45:              Updatekeys(key);
      46:          }
      47:          /// <summary>
      48:          /// 插入缓存
      49:          /// </summary>
      50:          /// <param name="key">key</param>
      51:          /// <param name="value">value</param>
      52:          /// <param name="expiration">过期时间</param>
      53:          public void Insert(string key, object value, TimeSpan expiration)
      54:          {
      55:              Cache.Store(StoreMode.Set, key, value, expiration);
      56:              Updatekeys(key);
      57:          }
      58:          /// <summary>
      59:          /// 根据key获取value
      60:          /// </summary>
      61:          /// <param name="key">key</param>
      62:          /// <returns></returns>
      63:          public object Get(string key)
      64:          {
      65:              return Cache.Get(key);
      66:          }
      67:          /// <summary>
      68:          /// 删除key的缓存的值
      69:          /// </summary>
      70:          /// <param name="key">key</param>
      71:          public void Remove(string key)
      72:          {
      73:              if (Exist(key))
      74:                  Cache.Remove(key);
      75:          }
      76:          /// <summary>
      77:          /// 检验key是否存在
      78:          /// </summary>
      79:          /// <param name="key"></param>
      80:          /// <returns></returns>
      81:          public bool Exist(string key)
      82:          {
      83:              if (Cache.Get(key) != null)
      84:                  return true;
      85:              else return false;
      86:          }
      87:          /// <summary>
      88:          /// 获取所有的key
      89:          /// </summary>
      90:          /// <returns></returns>
      91:          public List<string> GetCacheKeys()
      92:          {
      93:              return Cache.Get("keys") as List<string>;
      94:   
      95:          }
      96:          /// <summary>
      97:          /// 清空缓存
      98:          /// </summary>
      99:          public void Flush()
     100:          {
     101:              foreach (string s in GetCacheKeys())
     102:              {
     103:                  Remove(s);
     104:              }
     105:          }
     106:          /// <summary>
     107:          /// 更新key
     108:          /// </summary>
     109:          /// <param name="key">key</param>
     110:          private void Updatekeys(string key)
     111:          {
     112:              List<string> keys = new List<string>();
     113:              //读取本地keys
     114:              if (Cache.Get("keys") != null)
     115:                  keys = Cache.Get("keys") as List<string>;
     116:              //如果keys中不存在
     117:              if (!keys.Contains(key.ToLower()))
     118:                  keys.Add(key);
     119:              Cache.Store(StoreMode.Set, "keys", keys);
     120:          }
     121:          #endregion
     122:      }
     123:  }

    缓存工厂,用来创建缓存

       1:  using System;
       2:  using System.Collections.Generic;
       3:  using System.Linq;
       4:  using System.Text;
       5:  using System.Configuration;
       6:   
       7:  namespace CacheStorage
       8:  {
       9:   
      10:      /// <summary>
      11:      /// 缓存工厂
      12:      /// </summary>
      13:      public class CacheFactory
      14:      {
      15:          /// <summary>
      16:          /// 缓存类别
      17:          /// </summary>
      18:          public enum CacheType
      19:          {
      20:              //默认缓存
      21:              DefaultCache = 0,
      22:              /// <summary>
      23:              /// 分布式Memcached缓存
      24:              /// </summary>
      25:              MemcachedCache = 1
      26:          }
      27:          /// <summary>
      28:          /// 初始化
      29:          /// </summary>
      30:          /// <returns></returns>
      31:          public static ICacheStorage CreateCacheFactory()
      32:          {
      33:             string Cache=ConfigurationManager.AppSettings["CacheType"];
      34:             if (CacheType.MemcachedCache.ToString ()== Cache)
      35:             {
      36:                 return new MemcachedCache();
      37:             }
      38:             else
      39:                 return new DefaultCacheAdapter();
      40:          }
      41:      }
      42:  }
    在webconfig中配置缓存类别,
    然后在客户端,配置缓存
    image

    image

    客户端调用就见得多了,

    image

    然后,我们的后台需要一个管理缓存的模块,

    image

    可以动态配置,内容页的缓存时间,等等

       1:  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
       2:   
       3:  <html xmlns="http://www.w3.org/1999/xhtml">
       4:  <head>
       5:      <title>缓存管理</title>
       6:       <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
       7:      <link href="../css/demo.css" rel="stylesheet" type="text/css" />
       8:   
       9:      <script src="../scripts/jquery-1.6.2.min.js" type="text/javascript"></script>
      10:   
      11:      <script src="../scripts/miniui/miniui.js" type="text/javascript"></script>
      12:   
      13:      <link href="../scripts/miniui/themes/default/miniui.css" rel="stylesheet" type="text/css" />
      14:      <link href="../scripts/miniui/themes/icons.css" rel="stylesheet" type="text/css" />
      15:  </head>
      16:  <body>
      17:    <div class="mini-toolbar">
      18:          <h1>
      19:              缓存管理</h1>
      20:      </div>
      21:      <div id="datagrid1" class="mini-datagrid" style=" 100%; height: 400px;" allowresize="true"
      22:          url="Data/UrlInfo.ashx?method=SearchCacheInfo" idfield="Id" multiselect="false">
      23:          <div property="columns">
      24:              <div type="checkcolumn">
      25:              </div>
      26:              <div id="deal" name="action" width="100" headeralign="center" align="center" renderer="onActionRenderer"
      27:                  cellstyle="padding:0;">
      28:                  操作
      29:              </div>
      30:              <div field="Name" width="100" headeralign="center" allowsort="true">
      31:                  缓存标识</div>
      32:              <div field="Day" width="100"> <input  class="mini-spinner"  property="editor" value="0"  minValue="1" maxValue="365" />
      33:                  天</div>
      34:              <div field="Hour" width="100">小时
      35:                  <input  class="mini-spinner"  property="editor"  minValue="1" maxValue="365" /></div>
      36:              <div field="Title" width="100">
      37:                  缓存名称</div>
      38:          </div>
      39:      </div>
      40:   
      41:      <script type="text/javascript">
      42:          mini.parse();
      43:   
      44:          var grid = mini.get("datagrid1");
      45:        //  grid.load();
      46:          grid.sortBy("Name", "desc");
      47:   
      48:          grid.set({ footerStyle: "padding-right:10px;" });
      49:    function onActionRenderer(e) {
      50:              var grid = e.sender;
      51:              var record = e.record;
      52:              var uid = record._uid;
      53:              var rowIndex = e.rowIndex;
      54:   
      55:              var s = ' <a class="Edit_Button" href="javascript:editRow(\'' + uid + '\')">编辑</a>';
      56:   
      57:              if (grid.isEditingRow(record)) {
      58:                  s = '<a class="Update_Button" href="javascript:updateRow(\'' + uid + '\')">更新</a>'
      59:                      + '<a class="Cancel_Button" href="javascript:cancelRow(\'' + uid + '\')">取消</a>'
      60:              }
      61:              return s;
      62:          }
      63:            function editRow(row_uid) {
      64:              var row = grid.getRowByUID(row_uid);
      65:              if (row) {
      66:                  grid.cancelEdit();
      67:                  grid.beginEditRow(row);
      68:              }
      69:          }
      70:          function cancelRow(row_uid) {            
      71:              grid.reload();
      72:          }
      73:          function updateRow(row_uid) {
      74:              var row = grid.getRowByUID(row_uid);
      75:              var rowData = grid.getEditRowData(row);
      76:              grid.loading("保存中,请稍后......");
      77:              var json=mini.encode(rowData);
      78:              $.ajax({
      79:                  url: "Data/UrlInfo.ashx?method=UpdateCacheInfo",
      80:                  data: {CacheInfo:json },
      81:                  success: function (text) {
      82:                      grid.reload();
      83:                  
      84:                  },
      85:                  error: function (jqXHR, textStatus, errorThrown) {
      86:                      alert(jqXHR.responseText);
      87:                  }
      88:              });
      89:   
      90:          }
      91:    
      92:        
      93:   
      94:   
      95:      </script>
      96:   
      97:  </body>
      98:  </html>
    后台处理:
       1:    /// <summary>
       2:      /// 更新缓存信息
       3:      /// </summary>
       4:      /// <param name="context"></param>
       5:      public void UpdateCacheInfo(HttpContext context)
       6:      {
       7:          string CacheInfo = context.Request["CacheInfo"];
       8:        CacheInfo=CacheInfo.Trim(new char[] { '[', ']' });
       9:        JObject o = JObject.Parse(CacheInfo);
      10:      string Id=(string)o.SelectToken("Id");
      11:      int Day = (int)o.SelectToken("Day");
      12:      int Hour = (int)o.SelectToken("Hour");
      13:      context.Response.Write(new CacheManage().UpdateCacheInfo(Id, Day, Hour));
      14:      }
      15:      /// <summary>
      16:      ///  查询缓存信息
      17:      /// </summary>
      18:      /// <param name="context"></param>
      19:      public void SearchCacheInfo(HttpContext context)
      20:      {
      21:          //查询条件
      22:         // string key = context.Request["key"];
      23:          //分页
      24:          int pageIndex = Convert.ToInt32(context.Request["pageIndex"]);
      25:          int pageSize = Convert.ToInt32(context.Request["pageSize"]);
      26:          ////字段排序
      27:          //String sortField = context.Request["sortField"];
      28:          //String sortOrder = context.Request["sortOrder"];
      29:          //JSON 序列化
      30:          string json = new CacheManage().GetCacheAllInfoForMiniUIJson(pageIndex,pageSize);
      31:          context.Response.Write(json);
      32:      }

    这样我们一个简单的完整的缓存模块就设计完了,可以发现,这样我们的缓存管理就容易得多了.

    设计需要思考,程序员更需要思考,深入去学习软件思想,架构,而不仅仅停留在简单

    的工作,软件的复杂在于做大,软件的扩大,让软件的复杂度成指数级增长,所以更需

    要架构,深层次的去研究软件理论,软件精华!

     

  • 相关阅读:
    php学习推荐
    python 安装numpy报错
    PHP最基础
    php自定义错误函数
    phpMyAdmin安装
    php链接mysql提示:Call to undefined function mysql_connect()
    POJ 1005 解题报告
    亚马逊在线笔试(2014/10/9)
    LeetCode 题目 word break 思路剖析与改进
    Dijkstra单源最短路算法的C++实现
  • 原文地址:https://www.cnblogs.com/iverson3/p/2567212.html
Copyright © 2020-2023  润新知