大家都知道用系統默認的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