1. 程式人生 > >.Net 基於Memcache叢集的分散式Session

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

簡述

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