本篇博客记录一下我在实习的公司的后台管理系统开发框架中学习到的一种关于网站的缓存(Cache)的实现方法,我会在弄懂的基础上,将该方法在.net core上进行实现。因为公司开发都是基于.net framework的,但是在.net 这一块,.net framework正在逐渐被.net core所取代,而目前公司的前辈们由于开发任务较重,并没有着手使用.net core的打算,所以,我自己打算为公司搭建一个基于.net core的后台开发框架,这对自己是一个挑战,但收获还是很大的,在这个过程中,我学到了很多。下面我记录一下我们公司关于网站设计中Cache的一种设计与实现方法(先说在.net mvc下的实现方法,后续会写另一篇.net core的实现方法):

  • 总体设计:

  我们知道的缓存一般分为3种,分别是 Cookies,Session和Cache,这三种的区别和使用场景我在这里就不说了,网上有大神的博客说的很清楚。Cookies主要用于客户端,Session和Cache用于服务端,本篇主要讲Cahe的使用。Cache存储于服务器的内存中,允许自定义如何缓存数据项,以及缓存时间有多长。当系统内存缺乏时,缓存会自动移除很少使用或者使用优先级较低的缓存项以释放内存。Cache的使用可以提高整个系统的运行效率。

Cache在使用上也是(key,value)形式的,关于插入、获取、移除什么的,都可以在Cache类中去查看,这里贴出Cache这个类的内容:

#region 程序集 System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Web.dll
#endregionusing System.Collections;
using System.Reflection;namespace System.Web.Caching
{//// 摘要://     Implements the cache for a Web application. This class cannot be inherited.[DefaultMember("Item")]public sealed class Cache : IEnumerable{
public static readonly DateTime NoAbsoluteExpiration;
public static readonly TimeSpan NoSlidingExpiration;
public Cache();
public object this[string key] { get; set; }
public int Count { get; }
public long EffectivePrivateBytesLimit { get; }
public long EffectivePercentagePhysicalMemoryLimit { get; }
public object Add(string key, object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheItemRemovedCallback onRemoveCallback);
public object Get(string key);
public IDictionaryEnumerator GetEnumerator();
public void Insert(string key, object value);
public void Insert(string key, object value, CacheDependency dependencies);public void Insert(string key, object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheItemRemovedCallback onRemoveCallback);public object Remove(string key);}
}

可以看到里面有Add,Get,Insert之类的东西,这些用法网上也有很清楚的讲述,我也不赘述,也说不清楚,哈哈。

下面,结合上面那张示意图,来说明一下我要讲的缓存设计,个人感觉还是比较好的。

  <key,value>的形式,就是一个value对应一个key,通过key可以设置value的值,也可以获取value的值。在这里我们把 每个用户登录时生成的一个唯一的 id 做为 cache的key,然后把希望放到缓存中的数据作为value,进行缓存数据的处理。但是,我们放到value中的值,可能是有不同用途不同种类的一些值,比如,登录用户的基本信息,该系统存储的菜单数据,这两个就是用途完全不相干的两类数据,怎么存储呢?再另外使用一个key值不同的cache,这应该也是可以的。但是,我们这里讲的方法只使用一个Cache。

  具体做法呢,就是把这个value定义为一个 Dictionary<key,value>类型的值,这样在value里面,我们就可以通过设置不同的key值,来存储不同用途的缓存数据了。

  • 第一步

 首先,先定义一个存储value数据的类,代码如下:

UserCache.cs

using System.Collections.Generic;namespace Common
{public class UserCache{private readonly Dictionary<string, object> cacheDictionary = new Dictionary<string, object>();private readonly object lockObj = new object();/// <summary>/// 索引器/// </summary>/// <param name="key">key</param>/// <returns>缓存对象</returns>public object this[string key]{get{lock (lockObj){return cacheDictionary.ContainsKey(key) ? cacheDictionary[key] : null;}}set{lock(lockObj){if (cacheDictionary.ContainsKey(key)){cacheDictionary[key] = value;}else{cacheDictionary.Add(key, value);}}}}public void Remove(string key){lock (lockObj){if(cacheDictionary.ContainsKey(key)){cacheDictionary.Remove(key);}}}public void Clear(){lock(lockObj){cacheDictionary.Clear();}}}
}

上面的代码,用到了一个索引器,这使得我们可以像数组那样用 XXX[index]这样的方法访问和设置数据,从代码中我们可以看到,这个类最终都实现对 cacheDictionary 这个字典的操作,因为我们的数据都存储在这个字典中。不管你想存储什么数据只需要定义一个key值,然后存储到字典中即可。

  • 第二步

  定义好UserCache.cs后,我们再来写关于缓存操作的类:

  先定义缓存操作类,然后书写关于缓存操作的代码:

WebCache.cs(部分)

using System;
using System.Web;
using System.Web.Caching;
using Common;namespace Console
{/// <summary>/// 缓存操作类/// </summary>public class WebCache{#region 私有变量private const string UserIdentifyKey = "CacheUserIdentifyKey";#endregion#region 私有方法private static string GetUserIdentify(){if (HttpContext.Current.Session[UserIdentifyKey] != null)return HttpContext.Current.Session[UserIdentifyKey].ToString();var identify = Guid.NewGuid().ToString();HttpContext.Current.Session[UserIdentifyKey] = identify;return identify;}private static UserCache GetUserCache(){var identify = GetUserIdentify();if (HttpContext.Current.Cache.Get(identify) == null){HttpContext.Current.Cache.Insert(identify, new UserCache(), null, Cache.NoAbsoluteExpiration,new TimeSpan(0, 20, 0), CacheItemPriority.High, CacheRemovedCallback);}return HttpContext.Current.Cache.Get(identify) as UserCache;}/// <summary>/// 缓存被移除时触发/// </summary>/// <param name="key">被移除的缓存的key</param>/// <param name="value">被移除的缓存的值</param>/// <param name="reason">移除原因</param>private static void CacheRemovedCallback(string key, object value, CacheItemRemovedReason reason){// 缓存被移除时执行的操作// 如果是手动移除,则不处理//if (reason == CacheItemRemovedReason.Removed)//    return;// 此处访问页面会报错,暂时注释掉// ShowNotification(MessageType.Warning, "警告", "由于您太久没操作页面已过期,请重新登录!", true);
        }#endregion}
}

首先看上面的代码:

上面三段代码中,核心的代码是第二段,需要注意的是,都是静态方法:

 GetUserCache() 方法

当然,我们还是从第一段代码开始说起,

GetUserIdentify()
        private static string GetUserIdentify(){if (HttpContext.Current.Session[UserIdentifyKey] != null)return HttpContext.Current.Session[UserIdentifyKey].ToString();var identify = Guid.NewGuid().ToString();HttpContext.Current.Session[UserIdentifyKey] = identify;return identify;}

在一个用户登录之初,我们首先给这个用户生成一个唯一的用户 id ,然后把这个id保存到 Session中 (Session也是<key,value>形式的)。在第二段代码中,通过 GetUserIdentify()方法获取用户的唯一 id,然后把这个唯一 id作为 Cache的key值。

然后,我们来看第二段代码:

 GetUserCache():
        private static UserCache GetUserCache(){var identify = GetUserIdentify();if (HttpContext.Current.Cache.Get(identify) == null){HttpContext.Current.Cache.Insert(identify, new UserCache(), null, Cache.NoAbsoluteExpiration,new TimeSpan(0, 20, 0), CacheItemPriority.High, CacheRemovedCallback);}return HttpContext.Current.Cache.Get(identify) as UserCache;}

这段代码,首先判断Cache中是否有值(是否存在这个key的Cache),若不存在,则创建一个(代码中的 new UserCache())。.net framework中Cache操作使用 HttpContext.Current.Cache,Insert后有若干个参数,意思分别是:

identify:key值;

new UserCache():value值;第三个参数是:缓存依赖项 CacheDependency ,这里是 null;
Cache.NoAbsoluteExpiration:绝对过期时间 ,这里设置为无绝对过期时间;
new TimeSpan(0, 20, 0):这是滑动过期时间,此处设置为 20 minite;
CacheItemPriority.High:缓存优先级,此处为 high;
CacheRemovedCallback: 缓存移除时的回调函数,这个回调函数的参数是固定写法,必须按照规定写,三个参数以及参数类型 不可缺少也不可写错,否则会报错;(具体可见上面的第三段代码)

上面说到,若不存在,则创建一个 ,若存在,那么就直接返回即可。

接下来,在WebCache.cs中定义一些公共方法,用来供外界的方法调用,以实现对缓存的操作,代码如下:WebCache.cs(全):
 
using System;
using System.Web;
using System.Web.Caching;
using Common;namespace Console
{/// <summary>/// 缓存操作类/// </summary>public class WebCache{#region 私有变量private const string UserIdentifyKey = "CacheUserIdentifyKey";#endregion#region 公共方法/// <summary>/// 获取缓存/// </summary>/// <param name="key">键</param>/// <returns></returns>public static object GetCache(string key){return GetUserCache()[key];}/// <summary>/// 设置缓存/// </summary>/// <param name="key">键</param>/// <param name="value">值</param>/// <returns></returns>public static bool SetCache(string key, object value){try{var userCache = GetUserCache();userCache[key] = value;return true;}catch{return false;}}/// <summary>/// 清空缓存/// </summary>/// <returns></returns>public static bool ClearCache(){try{// 只清除缓存内容// GetUserCache().Clear();// 直接从Cache里移除var identify = GetUserIdentify();HttpContext.Current.Cache.Remove(identify);return true;}catch{return false;}}/// <summary>/// 移除缓存/// </summary>/// <param name="key">键</param>/// <returns></returns>public static bool RemoveCache(string key){try{GetUserCache().Remove(key);return true;}catch{return false;}}#endregion#region 私有方法private static string GetUserIdentify(){if (HttpContext.Current.Session[UserIdentifyKey] != null)return HttpContext.Current.Session[UserIdentifyKey].ToString();var identify = Guid.NewGuid().ToString();HttpContext.Current.Session[UserIdentifyKey] = identify;return identify;}private static UserCache GetUserCache(){var identify = GetUserIdentify();if (HttpContext.Current.Cache.Get(identify) == null){HttpContext.Current.Cache.Insert(identify, new UserCache(), null, Cache.NoAbsoluteExpiration,new TimeSpan(0, 20, 0), CacheItemPriority.High, CacheRemovedCallback);}return HttpContext.Current.Cache.Get(identify) as UserCache; // as是一种强制类型转化的方式}/// <summary>/// 缓存被移除时触发/// </summary>/// <param name="key">被移除的缓存的key</param>/// <param name="value">被移除的缓存的值</param>/// <param name="reason">移除原因</param>private static void CacheRemovedCallback(string key, object value, CacheItemRemovedReason reason){// 缓存被移除时执行的操作// 如果是手动移除,则不处理//if (reason == CacheItemRemovedReason.Removed)//    return;// 此处访问页面会报错,暂时注释掉// ShowNotification(MessageType.Warning, "警告", "由于您太久没操作页面已过期,请重新登录!", true);
        }#endregion}
}

依次定义了GetCache(),SetCache(),RemoveCache(),ClearCache()四个方法,供外界调用,来实现对缓存的操作。 
到这里,基本上关于这个Cache的实现就已经讲完了,下面,给出一段代码,做一个使用的示例。
        private const string LoginUserKey = "CacheKey-LoginUserCacheKey";
/// <summary>/// 获取或设置当前登录用户/// </summary>public static User LoginUser{get { return WebCache.GetCache(LoginUserKey) as User; }set { WebCache.SetCache(LoginUserKey, value); }}

 SetCache():
WebCache.SetCache(key, value);

RemoveCache(): 
RemoveCache(key); //移除字典中某个缓存值

ClearCache();
ClearCache(); //清空缓存的字典

关于这个缓存设计,就记录到这里了,关于.net core下的实现,因为.net core下并没有System.Web这个类,所以它的Cache实现方式,与.net 下的实现方式有些区别,这个,我会另起一篇博客去记录。

说明:本片博客并没有完整的demo,所有的代码都已贴出。

转载于:https://www.cnblogs.com/CherishTheYouth/p/CherishTheYouth_2019_0509.html

一种小型后台管理系统通用开发框架中的Cache缓存设计相关推荐

  1. Thinkphp 6 + Vue 2 + ElementUI + Vxe-table 前后端分离的,一键生成代码和API接口的,通用后台管理系统 快速开发框架,开发小程序和APP的推荐框架!

    Thinkphp 6 + Vue 2 + ElementUI + Vxe-table 前后端分离的,一键生成代码和API接口的,通用后台管理系统 快速开发框架,开发小程序和APP的推荐框架! 概述 R ...

  2. Axure RP中后台管理系统通用原型模板

    Axure RP中后台管理系统通用原型方案 v2是一套通用型的中后台信息系统原型方案,可以快速扩展并输出标准美观的中后台产品原型,极大的提升输出效率和节省协作成本.方案中提供了几十套不同风格和结构的系 ...

  3. Axure通用版电商后台管理系统+通用版移动端商城商户端+电商管理系统+对账管理+消息管理+内容管理+运营管理、会员管理、订单管理、促销管理、财务管理+通用版商城前后端电商系统+电商用户数据大屏看板

    作品介绍:Axure通用版电商后台管理系统+通用版移动端商城商户端+电商管理系统+对账管理+消息管理+内容管理+运营管理.会员管理.订单管理.促销管理.财务管理+通用版商城前后端电商系统+电商用户数据 ...

  4. 基于前端Vue后端.NetCore Web后台管理系统通用开本框架采用前后端分离技术,前端使用vue2.6.0,后端使用.netcore3.1,支持跨平台、多租户

    基于前端Vue后端.NetCore Web后台管理系统通用开本框架采用前后端分离技术,前端使用vue2.6.0,后端使用.netcore3.1,支持跨平台.多租户.支持MySQL/SQLServer/ ...

  5. 聊聊微服务架构中的多级缓存设计

    大家好,我是不才陈某~ 今天我们来聊聊缓存这个话题,看看在微服务环境下如何设计有效的多级缓存架构.主要涉及三方面内容: Web 应用的客户端缓存: 应用层静态资源缓存: 服务层多级缓存. 首先,咱们先 ...

  6. vue后台管理系统(通用模板)

    后台管理通用框架 源码: GitHub 亲测有效: 预览地址 目前 包含 动态侧边导航栏渲染,面包屑,通知,主题,富文本等- 1.登陆 2.工作台 3.通知 4.主题 5.发邮件 6.通知详情 目前可 ...

  7. 第 4-4 课:Spring Boot 中使⽤ Cache 缓存的使⽤

    我们知道绝⼤多数的⽹站/系统,最先遇到的⼀个性能瓶颈就是数据库,使⽤缓存做数据库的前置缓存,可以 ⾮常有效地降低数据库的压⼒,从⽽提升整个系统的响应效率和并发量. 以往使⽤缓存时,通常创建好缓存⼯具类 ...

  8. Vue中的cache缓存,原来是这样啊

    上篇文章写了arrify转数组,无论传给arrify什么样的数据都是返回一个数组,相对而言还是比较简单的.这篇文章分享一个比较有意思的东西,那就是Vue中如何实现cache缓存的.提前揭晓答案–闭包. ...

  9. 基于微信小程序的音乐播放器系统+后台管理系统(SSM+mysql)-JAVA.VUE【数据库设计、论文、源码、开题报告】

    功能介绍 管理员:首页,个人中心,用户管理,音乐类型管理,音乐信息管理,音乐专辑管理,fm电台管理,音乐论坛管理,系统管理等 普通用户:登录注册.首页.音乐信息.音乐专辑.音乐论坛.我的等 数据库脚本 ...

最新文章

  1. ASP.NET技巧:两个截取字符串的实用方法
  2. oracle元字符,oracle中正则表达式的基本元字符
  3. mysql 分组排序取前n_mysql分组排序取前N条记录的最简洁的单条sql ! | 学步园
  4. hydra安装及使用
  5. 计算机三级设计与应用题,计算机数据库三级设计与应用题.pdf
  6. metasploit连接postgresql的问题(U盘启动kali linux)
  7. java math.floordiv,Math类的常用方法--田小江
  8. 风控中英文术语手册(银行_消费金融信贷业务)_version6
  9. 《Linux私房菜》——一、linux基础整理
  10. 泛雅计算机网络,2020超星泛雅网课计算机网络技术最新最全见面课答案
  11. 用KOPPT,大家的姿势对了没?
  12. hcie培训价格多少钱?
  13. MethodHandle.invoke and MethodHandle.invokeExact are only supported starting with Android O
  14. 理解Linux中的进程状态
  15. 开发用于互操作性的应用程序_云标准:确保云应用互操作性的工具
  16. 002/160 CrackMe Afkayas #1
  17. 爬取百度贴吧实战,python教你如何获取
  18. java-JQuery的使用
  19. 程序员小姐姐用代码实现《本草纲目》毽子操,刘畊宏亲自回复:很cool!
  20. 【人脸识别】Gabor+SVM比较PCA+SVM人脸识别【含GUI Matlab源码 685期】

热门文章

  1. Java抽象类与接口的区别
  2. Spring - Java/J2EE Application Framework 应用框架 第 8 章 源代码级的元数据支持
  3. Java虚拟机jvm 调优总结
  4. 你遇到过哪些理工科的实验高手,他们有哪些优秀的思维习惯?
  5. 用DPM(Deformable Part Model,voc-release3.1)算法在INRIA数据集上训练自己的人体检测模型
  6. 计算机网络探究一之利用双网卡主机共享上网
  7. 神经网络中的激活函数的作用和选择
  8. 初探 es6 promise
  9. JVM优化过程全记录
  10. 满纸荒唐言,一把辛酸泪--红楼一梦