一、前言
说起缓存,或许大家都不陌生,甚至是天天都在用!当然缓存也被分的越来越细,页面缓存、数据缓存、文件缓存等等。
其实呢,我个人觉得,主要还是两大类:数据的缓存和页面的缓存。数据缓存的话就包括所有跟数据扯上关系的都可以
归到这一类,至于页面缓存的话,就是把一些页面缓存起来,尤其是静态的页面,对访问速度可以说是杠杠的。本文主要
介绍的是数据的缓存。当然本文说是这Nancy中使用,但是这一块是通用的,无论你是在MVC、WebForm、甚至是最新的
Asp.Net Core都是基本一致的。可以选择的缓存类型又有很多,可以用微软自己的MemoryCache,可以用牛逼的Redis,当然
也可以用分布式缓存MemCached,如果问要怎么选的话,那就是视情况而定!
说起数据缓存,最直接想到的肯定就是对时间的缓存。在某个页面显示一个时间,缓存了10秒的话,那这10秒怎么刷新都是不换
变化的。这个可以说是理解缓存最最最简单的一个例子了。下面就来看看Demo吧。
二、用MemoryCache的Demo
先简单介绍一下MemoryCache吧,MemoryCache是位于System.Runtime.Caching下面的一个类。
里面具体的一些属性和方法可以参见msdn上的介绍
https://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache
值得一提的是Default这个属性。这个属性也是我们等下要用到的。MemoryCache中的实现用了单例模式,更具体的可以参见源码
http://referencesource.microsoft.com/#System.Runtime.Caching/System/Caching/MemoryCache.cs
好了,不废话了,开始正题了。
首先定义一个ICache的接口
1 namespace NancyFxDemo01.MyCache 2 { 3 public interface ICache 4 { 5 /// <summary> 6 /// 添加缓存对象 7 /// </summary> 8 /// <param name="key">缓存Key</param> 9 /// <param name="obj">要缓存的对象</param> 10 void Add(string key, object obj); 11 /// <summary> 12 /// 添加有时间限制的缓存对象 13 /// </summary> 14 /// <param name="key">缓存Key</param> 15 /// <param name="obj">要缓存的对象</param> 16 /// <param name="seconds">缓存时间</param> 17 void Add(string key, object obj, int seconds); 18 /// <summary> 19 /// 判断指定的Key是否已经有缓存数据 20 /// </summary> 21 /// <param name="key">缓存Key</param> 22 /// <returns>true/false</returns> 23 bool Exists(string key); 24 /// <summary> 25 /// 获取缓存的对象 26 /// </summary> 27 /// <typeparam name="T">缓存对象的类型</typeparam> 28 /// <param name="key">缓存Key</param> 29 /// <returns>缓存的对象</returns> 30 T Get<T>(string key); 31 /// <summary> 32 /// 移除缓存项 33 /// </summary> 34 /// <param name="key">缓存Key</param> 35 void Remove(string key); 36 } 37 }
这个接口应该没有什么好说的,了解过缓存的应该都是懂的,不过写的也不全,像清空缓存等方法还是没有写,不都都是挺好理解的。
有了接口,肯定会有实现!Cache就是基于MemoryCache实现的。
1 using System; 2 using System.Runtime.Caching; 3 namespace NancyFxDemo01.MyCache 4 { 5 public class Cache : ICache 6 { 7 private readonly MemoryCache _cache; 8 private readonly CacheItemPolicy _defaultCacheItemPolicy; 9 public Cache() 10 { 11 _cache = MemoryCache.Default; 12 _defaultCacheItemPolicy = new CacheItemPolicy { SlidingExpiration = TimeSpan.FromSeconds(60 * 2) }; 13 } 14 /// <summary> 15 /// 添加缓存对象 16 /// </summary> 17 /// <param name="key">缓存Key</param> 18 /// <param name="obj">要缓存的对象</param> 19 public void Add(string key, object obj) 20 { 21 var cacheItem = new CacheItem(key, obj); 22 _cache.Set(cacheItem, _defaultCacheItemPolicy); 23 } 24 /// <summary> 25 /// 添加有时间限制的缓存对象 26 /// </summary> 27 /// <param name="key">缓存Key</param> 28 /// <param name="obj">要缓存的对象</param> 29 /// <param name="seconds">缓存时间</param> 30 public void Add(string key, object obj, int seconds) 31 { 32 _cache.Set(key, obj, DateTimeOffset.Now.AddSeconds(seconds)); 33 } 34 /// <summary> 35 /// 判断指定的Key是否已经有缓存数据 36 /// </summary> 37 /// <param name="key">缓存Key</param> 38 /// <returns>true/false</returns> 39 public bool Exists(string key) 40 { 41 return _cache.Get(key) != null; 42 } 43 /// <summary> 44 /// 获取缓存的对象 45 /// </summary> 46 /// <typeparam name="T">缓存对象的类型</typeparam> 47 /// <param name="key">缓存Key</param> 48 /// <returns>缓存的对象</returns> 49 public T Get<T>(string key) 50 { 51 return (T)_cache.Get(key); 52 } 53 /// <summary> 54 /// 移除缓存项 55 /// </summary> 56 /// <param name="key">缓存Key</param> 57 public void Remove(string key) 58 { 59 _cache.Remove(key); 60 } 61 } 62 }
前面说过,会用到Default这个属性。我是在构造函数中去赋值的。那些常规的操作就是通过MemoryCache.Default去进行操作的!
下面就是Nancy的代码了,如果对Nancy还有疑问的话,可以去看看我前面介绍Nancy的文章。
1 using System; 2 using Nancy; 3 using NancyFxDemo01.MyCache; 4 namespace NancyFxDemo01 5 { 6 public class FirstModule : NancyModule 7 { 8 public FirstModule() 9 { 10 Get["/"] = _ => 11 { 12 string time = DateTime.Now.ToString(); 13 ICache cache = new Cache(); 14 if (!cache.Exists("time")) 15 { 16 cache.Add("time", time , 10); 17 return DateTime.Now.ToString(); 18 } 19 return cache.Get<string>("time"); 20 }; 21 } 22 } 23 }
效果图:
可以看到,这个时间被缓存了10秒,十秒之后才会发生变化。
三、用Redis的Demo
Redis可以说是神器啊,它的性能确实比memcached要好一些。
要用Redis,肯定要先装一个redis,这个是必不可少的,本人装的是windows版,具体如下:
当然,这只是个大前提,要想去操作Redis还得用工具的,这个时候我们可以通过NuGet去安装
StackExchange.Redis 或者是 ServiceStack.Redis ,相信这两个是大家用的最多的。
示例用的是StackExchange.Redis这个包。
1 using System; 2 using Nancy; 3 using StackExchange.Redis; 4 namespace NancyFxDemo01 5 { 6 public class SecondModule : NancyModule 7 { 8 private string _host = "127.0.0.1"; 9 public SecondModule() 10 { 11 Get["/redis"] = _ => 12 { 13 string time = DateTime.Now.ToString(); 14 ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(_host); 15 IDatabase db = redis.GetDatabase(); 16 if (!db.KeyExists("time")) 17 { 18 db.StringSet("time", time, TimeSpan.FromSeconds(10)); 19 } 20 21 return db.StringGet("time").ToString() ; 22 }; 23 } 24 } 25 }
这个是在Nancy中使用Redis的代码,这里的话就没对Reids的操作进行封装,是直接在方法里面进行了操作。
下面是效果图
可以看到效果已经出来了!!!
至于memcached的话,就不在做Demo演示了。
四、总结
本文这两个例子比较简单,但是应该是通俗易懂的。不过篇幅基本都在介绍缓存,只是在Nancy中使用到了
这些知识而已。缓存说复杂的话,它并不那么复杂,无非就是读和写。但是说简单,它也并不简单,用的时机以及怎么用
对一个网站会带来很重要的影响。
后面有时间的话会用Nancy和Redis做一个复杂一点的例子。