zoukankan      html  css  js  c++  java
  • Redis作为缓存服务器

      1、ICache的Redis实现没有放在'Framework.Cache/Logic'中。如果是以前,我会认为这样不好。我会这样做,'Framework.Cache'项目引用Redis项目或直接从Nuget安装Redis,

    把实现定义在‘Framework.Cache/Logic’中,这样结构看起来很顺眼,‘这算是高内聚么!!!’。不过自从接触了IOC后,现在这样的结构似乎也很合理,没什么违和感。

    这就好似把‘IRepository’和‘Repositories’,一个放在Domain,一个放在Infrastructure

      2、当前比较稳定的Redis客户端(开源的程序包)有ServiceStack.Redis 和 StackExchange.Redis。我都用了一下,ServiceStatck的

    比较好用,不过我感觉后者的性能应该会稍好点

      3、关于ServiceStack.Redis中的接口,IRedisClient,ICacheClient,IRedisTypedClient<T>,IEntityStore<T>,IEntityStore。

    这些“乱七八糟”的接口和CRUD都有关系,中的有些方法看似好像是重复的,后续希望能整理出一篇结合源码,理论点的文章

      

    一、Framework.Cache

    接口ICache,定义缓存操作开放的方法

     1     public interface ICache
     2     {
     3         /// <summary>
     4         /// Gets all entries in the cache
     5         /// </summary>
     6         IEnumerable<KeyValuePair<string, object>> Entries { get; }
     7 
     8         /// <summary>
     9         /// Gets a cache item associated with the specified key or adds the item
    10         /// if it doesn't exist in the cache.
    11         /// </summary>
    12         /// <typeparam name="T">The type of the item to get or add</typeparam>
    13         /// <param name="key">The cache item key</param>
    14         /// <param name="baseMethod">Func which returns value to be added to the cache</param>
    15         /// <returns>Cached item value</returns>
    16         T Get<T>(string key, Func<T> baseMethod);
    17 
    18         /// <summary>
    19         /// Gets a cache item associated with the specified key or adds the item
    20         /// if it doesn't exist in the cache.
    21         /// </summary>
    22         /// <typeparam name="T">The type of the item to get or add</typeparam>
    23         /// <param name="key">The cache item key</param>
    24         /// <param name="baseMethod">Func which returns value to be added to the cache</param>
    25         /// <param name="cacheTime">Expiration time in minutes</param>
    26         /// <returns>Cached item value</returns>
    27         T Get<T>(string key, Func<T> baseMethod, int cacheTime);
    28 
    29         /// <summary>
    30         /// Gets a value indicating whether an item associated with the specified key exists in the cache
    31         /// </summary>
    32         /// <param name="key">key</param>
    33         /// <returns>Result</returns>
    34         bool Contains(string key);
    35 
    36         /// <summary>
    37         /// Removes the value with the specified key from the cache
    38         /// </summary>
    39         /// <param name="key">/key</param>
    40         void Remove(string key);
    41     }

    二、基于‘ServiceStack.Redis’的缓存实现

     1 public class SSRedisCache : ICache
     2     {
     3         private const string REGION_NAME = "$#SSRedisCache#$";
     4         private const int _DefaultCacheTime = 30;
     5         private readonly static object s_lock = new object();
     6 
     7         private IRedisClient GetClient()
     8         {
     9             return RedisManager.GetClient();
    10         }
    11 
    12         private IRedisClient GetReadOnlyClient()
    13         {
    14             return RedisManager.GetReadOnlyClient();
    15         }
    16 
    17         public IEnumerable<KeyValuePair<string, object>> Entries
    18         {
    19             get { throw new NotImplementedException(); }
    20         }
    21 
    22         public T Get<T>(string key, Func<T> baseMethod)
    23         {
    24             return Get<T>(key, baseMethod, _DefaultCacheTime);
    25         }
    26 
    27         public T Get<T>(string key, Func<T> baseMethod, int cacheTime)
    28         {
    29             using (var redisClient = GetClient())
    30             {
    31                 key = BuildKey(key);
    32 
    33                 if (redisClient.ContainsKey(key))
    34                 {
    35                     return redisClient.Get<T>(key);
    36                 }
    37                 else
    38                 {
    39                     lock (s_lock)
    40                     {
    41                         if (!redisClient.ContainsKey(key))
    42                         {
    43                             var value = baseMethod();
    44                             if (value != null) //请区别null与String.Empty
    45                             {
    46                                 redisClient.Set<T>(key, value, TimeSpan.FromMinutes(cacheTime));
    47                                 //redisClient.Save();
    48                             }
    49                             return value;
    50                         }
    51                         return redisClient.Get<T>(key);
    52                     }
    53                 }
    54             }
    55         }
    56 
    57         public bool Contains(string key)
    58         {
    59             using (var redisClient = GetReadOnlyClient())
    60             {
    61                 return redisClient.ContainsKey(BuildKey(key));
    62             }
    63         }
    64 
    65         public void Remove(string key)
    66         {
    67             using (var redisClient = GetClient())
    68             {
    69                 redisClient.Remove(BuildKey(key));
    70             }
    71         }
    72 
    73         private string BuildKey(string key)
    74         {
    75             return string.IsNullOrEmpty(key) ? null : REGION_NAME + key;
    76         }
    77 
    78     }

    三、基于‘StackExchange.Redis’的缓存实现

    1 <?xml version="1.0" encoding="utf-8"?>
    2 <packages>
    3   <package id="MsgPack.Cli" version="0.6.8" targetFramework="net45" />
    4   <package id="StackExchange.Redis" version="1.0.488" targetFramework="net45" />
    5   <package id="StackExchange.Redis.Extensions.Core" version="1.3.2.0" targetFramework="net45" />
    6   <package id="StackExchange.Redis.Extensions.MsgPack" version="1.3.2.0" targetFramework="net45" />
    7 </packages>
     1 public class SERedisCache : ICache
     2     {
     3         private const string REGION_NAME = "$#SERedisCache#$";
     4         private const int _DefaultCacheTime = 30;
     5         private readonly static object s_lock = new object();
     6 
     7         private StackExchangeRedisCacheClient GetClient()
     8         {
     9             return new StackExchangeRedisCacheClient(RedisServer.Connection, new MsgPackObjectSerializer());
    10         }
    11 
    12         public IEnumerable<KeyValuePair<string, object>> Entries
    13         {
    14             get { throw new NotImplementedException(); }
    15         }
    16 
    17         public T Get<T>(string key, Func<T> baseMethod)
    18         {
    19             return Get(key, baseMethod, _DefaultCacheTime);
    20         }
    21 
    22         public T Get<T>(string key, Func<T> baseMethod, int cacheTime)
    23         {
    24             using (var cacheClient = GetClient())
    25             {
    26                 key = BuildKey(key);
    27 
    28                 if (cacheClient.Exists(key))
    29                 {
    30                     return cacheClient.Get<T>(key);
    31                 }
    32                 else
    33                 {
    34                     lock (s_lock)
    35                     {
    36                         if (!cacheClient.Exists(key))
    37                         {
    38                             var value = baseMethod();
    39                             if (value != null) //请区别null与String.Empty
    40                             {
    41                                 cacheClient.Add<T>(key, value, TimeSpan.FromMinutes(cacheTime));
    42                             }
    43                             return value;
    44                         }
    45                         return cacheClient.Get<T>(key);
    46                     }
    47                 }
    48             }
    49         }
    50 
    51         public bool Contains(string key)
    52         {
    53             using (var cacheClient = GetClient())
    54             {
    55                 return cacheClient.Exists(BuildKey(key));
    56             }
    57         }
    58 
    59         public void Remove(string key)
    60         {
    61             using (var cacheClient = GetClient())
    62             {
    63                 cacheClient.Remove(BuildKey(key));
    64             }
    65         }
    66 
    67         private string BuildKey(string key)
    68         {
    69             return string.IsNullOrEmpty(key) ? null : REGION_NAME + key;
    70         }
    71 
    72     }

    完整代码(稍后) 会在另一篇文章关于Web API中附上

  • 相关阅读:
    AngularJS中实现无限级联动菜单
    理解AngularJS生命周期:利用ng-repeat动态解析自定义directive
    denounce函数:Javascript中如何应对高频触发事件
    Javascript中的循环变量声明,到底应该放在哪儿?
    优雅的数组降维——Javascript中apply方法的妙用
    如何利⽤360Quake挖掘某授权⼚商边缘站点漏洞
    Java课程设计--网络聊天室
    DS博客作业08--课程总结
    DS博客作业07--查找
    DS博客作业06--图
  • 原文地址:https://www.cnblogs.com/frozenzhang/p/5439940.html
Copyright © 2011-2022 走看看