曾南华

Asp.net Mvc 自定义Session (一),

  大家都知道用系统默认的session 会存在这样的问题 如果用户过多的话 session 会自动消亡,而且不能支持分布式和集群。

  这系列博客主要讲解  怎样 解决用户过多的session自动消亡,和分布式集群

  使用例子

 Session["test"] = "啄木鸟";  
完全不改变系统的使用风格,可以直接升级系统;

 

 

   在这里我们主要用的 HttpRuntime.cache 和 memcache。 希望读者这跟着我的思路,一步一步来设计自定义Session

  首先,我们想既然有两个数据存取工具,就必须有一个接口  来解耦使用的他的类,从而可以轻而易举的切换数据存储工具,而不影响使用它的类

  接口如下:

  

 public interface ICache
    {
        /// <summary>
        /// 数据加入缓存,并使用全局配置的过期时间
        /// </summary>
        /// <param name="key"></param>
        /// <param name="obj">数据</param>
        void Put(string key, object obj);
        /// <summary>
        /// 数据加入缓存,并指定过期时间(分钟)
        /// </summary>
        /// <param name="key"></param>
        /// <param name="obj">数据</param>
        /// <param name="expireMinutes">过期时间</param>
        void Put(string key, object obj, int expireMinutes);
        /// <summary>
        /// 拿出缓存数据
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        object Get(string key);
        /// <summary>
        /// 手动删除缓存数据
        /// </summary>
        /// <param name="key"></param>
        void Delete(string key);
    }

  接下来 我们来实现这两个数据存储工具类

  一个是系统自带的HttpRuntime.cache

  

 public class RuntimeCache:ICache
    {
        readonly static System.Web.Caching.Cache httpRuntimeCache = System.Web.HttpRuntime.Cache;
        readonly static int _expireMinutes = 20;  //ConfigConstants.ConfigManager.Config.Cache_ExpireMinutes;配置默认多少秒过时
        public void Put(string key, object obj)
        {
            httpRuntimeCache.Insert(key,obj);
        }

        public void Put(string key, object obj, int expireMinutes)
        {
            httpRuntimeCache.Insert(key, obj, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(expireMinutes));
        }

        public object Get(string key)
        {
            return httpRuntimeCache.Get(key);
        }

        public void Delete(string key)
        {
             httpRuntimeCache.Remove(key);
        }
    }


  上面这个工具我想大家多知道,如果不知道的可以百度 HttpRuntime.Cache  来学习 ,在这里我就不讲解了(其实里面有很多的设计思路可以学习)

 

  另一个的就是memcache,redis 我会在后面加上去

  

 public class MemcacheCache:ICache
    {
        private static readonly MemcachedClient m_memcachedClient;
        private static string m_memcacheStr = ConfigConstants.FrameConfigManager.Config.MemcacheStr ?? "127.0.0.1:11211";
        static MemcacheCache()
        {

            string[] servers = m_memcacheStr.Split(',');//
            try
            {
                //初始化池
                SockIOPool pool = SockIOPool.GetInstance();
                pool.SetServers(servers);
                pool.InitConnections = 3;
                pool.MinConnections = 3;
                pool.MaxConnections = 5;
                pool.SocketConnectTimeout = 1000;
                pool.SocketTimeout = 3000;
                pool.MaintenanceSleep = 30;
                pool.Failover = true;
                pool.Nagle = false;
                pool.Initialize();
                m_memcachedClient = new Memcached.ClientLibrary.MemcachedClient();
                m_memcachedClient.EnableCompression = false;
            }
            catch (Exception ex)
            {
                int i = 0;
            }
        }

        public void Put(string key, object obj)
        {
            m_memcachedClient.Set(key, obj);
        }

        public void Put(string key, object obj, int expireMinutes)
        {
            m_memcachedClient.Set(key, obj, DateTime.Now.AddMinutes(expireMinutes));
        }

        public object Get(string key)
        {
            return m_memcachedClient.Get(key);
        }

        public void Delete(string key)
        {
            m_memcachedClient.Delete(key);
        }
    }

    memcache的详细配置,可以找其他资料学习

  

    到这里为止,是不是感觉有点像我们的工厂模式 前段,没错就要用到工厂模式

     我们再新建一个类 叫做

    

 /// <summary>
    /// 缓存管理者
    /// </summary>
   public class CacheManager :Singleton<CacheManager>,ICache
    {
        #region 私有变量
        private static string _cacheProvider = ConfigConstants.FrameConfigManager.Config.Cache_Provider ?? "runtimecache";
        private ICache _iCache;
       
        #endregion

        #region 构造方法
        /// <summary>
        /// 类构造方法,对外不支持创建它的实例对象
        /// </summary>
        static CacheManager() { }
        private CacheManager()
        {
            switch (_cacheProvider.ToLower())
            { 
                case"runtimecache":
                    _iCache = new RuntimeCache();
                    break;
                case "memcachecache":
                    _iCache = new MemcacheCache();
                    break;
                default:
                    throw new ArgumentException("缓存提供者只支持RunTimeCache和RedisCache");
            }
        }
        #endregion 
        public void Put(string key, object obj)
        {
            _iCache.Put(key, obj);
        }

        public void Put(string key, object obj, int expireMinutes)
        {
            _iCache.Put(key,obj,expireMinutes);
        }

        public object Get(string key)
        {
            return _iCache.Get(key);
        }

        public void Delete(string key)
        {
            _iCache.Delete(key);
        }
    }

 

  我想这个类 大家都能看的懂,唯有这个Singleton<CacheManager> 大家可能有点 不能明白,因为这个是我自己分装的单例模式,只要继承了他,这个类就是单利了,我会再下一次博客讲明白怎样分装的。到这里我们就实现了使用和提供解耦,我 想告诉大家的就是设计模式会根据你的代码量来循循渐进,不要特意看设计模式

  我们有了这些准备,下一篇就好讲如何自定义session

  

 

posted @ 2016-05-21 09:23  啄木鸟¥  阅读(1880)  评论(5编辑  收藏  举报

曾南华