.Net 基於Memcache叢集的分散式Session
阿新 • • 發佈:2019-09-02
簡述
基於Memcache的Session大家都各有各的說法,比方說:當memcached叢集發生故障(比如記憶體溢位)或者維護(比如升級、增加或減少伺服器)時,使用者會無法登入,或者被踢掉線等等,每種技術各有優缺點,只是適應的場景不同罷了。
知識點補充
伺服器Memcache配置:https://www.cnblogs.com/chenyanbin/p/11415368.html
Memcache叢集配置:https://www.cnblogs.com/chenyanbin/p/11441490.html
Mvc校驗使用者是否登陸:https://www.cnblogs.com/chenyanbin/p/11397576.html
演示程式碼使用的其他完整類庫:https://www.cnblogs.com/chenyanbin/p/11186495.html
程式碼演示(.Net的Mvc架構):
登陸頁控制器
1 IBllSession bllSession = BllSessionFactory.GetCurrentBllSession(); //業務層基類 2 /// <summary> 3 /// 處理登陸的表單 4 /// </summary> 5 /// <returns></returns> 6 public ActionResult ProcessLogin() 7 { 8 try 9 { 10 string user_name = Request["LoginId"]; //使用者名稱 11 string user_pwd = Request["LoginPwd"]; //密碼 12 UserInfo model = new UserInfo(); //實體類 13 model.UName = user_name; //實體類賦值 14 model.UPwd = user_pwd; 15 if (bllSession.UserInfo.Select(model).Count > 0) //判斷使用者名稱密碼是否正確 16 { 17 //舊方法 18 //Session["loginUser"] = user_name; 19 20 //新方法 21 //Memcache+Cookie替代Session登陸 22 //立即分配一個標誌GUID,把標誌作為Memcache儲存資料的key,把使用者物件放到Memcache,把GUID寫到客戶端cookie裡面去 23 string userLoginId = Guid.NewGuid().ToString(); //生成一個隨機GUID 24 //將使用者的資料寫入Memcache 25 MemcacheHelper.AddCache(userLoginId, user_name, DateTime.Now.AddMinutes(20)); //Memcache幫助類 26 //往客戶端寫入Cookie 27 Response.Cookies["userLoginId"].Value= userLoginId; //將GUID寫入Cookie 28 return Content("ok"); 29 } 30 else 31 { 32 return Content("使用者名稱或密碼錯誤!你會登陸嗎?"); 33 } 34 } 35 catch (Exception ex) 36 { 37 throw ex; 38 } 39 }
過濾器基類(判斷使用者是否登陸)
1 using Sam.OA.Common; 2 using System; 3 using System.Web.Mvc; 4 5 namespace Sam.OA.WEBAPP.Controllers 6 { 7 /// <summary> 8 /// 控制器基類幫助類 9 /// 作者:陳彥斌 10 /// 更新時間:2019年9月1日17:43:10 11 /// </summary> 12 public class BaseController:Controller 13 { 14 public bool IsCheckedUserLogin = true; 15 protected override void OnActionExecuted(ActionExecutedContext filterContext) 16 { 17 base.OnActionExecuted(filterContext); 18 //校驗使用者是否已登入 19 if (IsCheckedUserLogin ) 20 { 21 //新方法 22 //使用Memcache+Cookie代替Session 23 if (Request.Cookies["userLoginId"] == null) 24 { 25 filterContext.HttpContext.Response.Redirect("/UserLogin/Index"); 26 return; 27 } 28 string userGuid = Request.Cookies["userLoginId"].Value; //拿到使用者的GUID 29 object obj = MemcacheHelper.GetCache(userGuid); 30 if (obj == null || obj.ToString() == "") 31 { 32 //使用者長時間不操作,超時 33 filterContext.HttpContext.Response.Redirect("/UserLogin/Index"); 34 } 35 //滑動視窗機制 36 MemcacheHelper.SetCache(userGuid, obj, DateTime.Now.AddMinutes(20)); 37 38 //舊方法Session 39 //if (filterContext.HttpContext.Session["loginUser"] == null) 40 //{ 41 // filterContext.HttpContext.Response.Redirect("/UserLogin/Index"); 42 //} 43 } 44 } 45 } 46 }
Memcache幫助類(MemcacheHelper.cs)
1 using Memcached.ClientLibrary; 2 using System; 3 4 namespace Sam.OA.Common 5 { 6 /// <summary> 7 /// Memcache快取幫助類 8 /// 作者:陳彥斌 9 /// 時間:2019年9月1日15:48:12 10 /// </summary> 11 public sealed class MemcacheHelper 12 { 13 private static MemcachedClient memcachedClient; 14 static MemcacheHelper() 15 { 16 //分散式Memcached伺服器ip 埠 17 string strAppMemcached = DbUtil.memcacheServiceList; 18 if (strAppMemcached==""|| strAppMemcached==null) 19 { 20 throw new Exception("Memcache遠端伺服器Ip和埠未配置"); 21 } 22 string[] servers = strAppMemcached.Split(','); //Memcache機器IP 23 //初始化池 24 SockIOPool pool = SockIOPool.GetInstance(); 25 pool.SetServers(servers); //關聯連線池 26 pool.InitConnections = 3; //初始化連結 27 pool.MinConnections = 3; //最小連線數 28 pool.MaxConnections = 5; //最大連線數 29 pool.SocketConnectTimeout = 1000; //Socket超時連線時間 30 pool.SocketTimeout = 3000; //Socket超時時間 31 pool.MaintenanceSleep = 30; //Socket休眠時間 32 pool.Failover = true; 33 pool.Nagle = false; 34 pool.Initialize(); //初始化 35 //客戶端例項 36 if (memcachedClient == null) 37 { 38 memcachedClient = new MemcachedClient(); 39 } 40 memcachedClient.EnableCompression = false; //啟動壓縮 41 } 42 /// <summary> 43 /// 獲取Memcache快取資料 44 /// </summary> 45 /// <param name="CacheKey">鍵</param> 46 /// <returns></returns> 47 public static object GetCache(string CacheKey) 48 { 49 return memcachedClient.Get(CacheKey); 50 } 51 /// <summary> 52 /// 設定Memcache快取資料 53 /// </summary> 54 /// <param name="CacheKey">鍵</param> 55 /// <param name="CacheValue">值</param> 56 public static void AddCache(string CacheKey, object CacheValue) 57 { 58 memcachedClient.Add(CacheKey, CacheValue); 59 } 60 /// <summary> 61 /// 設定Memcache快取資料 62 /// </summary> 63 /// <param name="CacheKey">鍵</param> 64 /// <param name="CacheValue">值</param> 65 /// <param name="expDate">過期時間</param> 66 public static void AddCache(string CacheKey, object CacheValue, DateTime expDate) 67 { 68 memcachedClient.Add(CacheKey, CacheValue,expDate); 69 } 70 /// <summary> 71 /// 設定Memcache快取資料,key存在則更新,否則新增 72 /// </summary> 73 /// <param name="CacheKey">鍵</param> 74 /// <param name="CacheValue">值</param> 75 public static void SetCache(string CacheKey, object CacheValue) 76 { 77 memcachedClient.Set(CacheKey, CacheValue); 78 } 79 /// <summary> 80 /// 設定Memcache快取資料,key存在則更新,否則新增 81 /// </summary> 82 /// <param name="CacheKey">鍵</param> 83 /// <param name="CacheValue">值</param> 84 /// <param name="expDate">過期時間</param> 85 public static void SetCache(string CacheKey, object CacheValue, DateTime expDate) 86 { 87 memcachedClient.Set(CacheKey, CacheValue, expDate); 88 } 89 } 90 }
覺得對你有幫助的話,幫忙推薦下,還有不懂的地方,歡迎下方留言,明天繼續更新Redis