.Net 基於Memcache集群的分散式Session

  • 2019 年 10 月 3 日
  • 筆記

簡述

  基於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!~~