.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!~~

posted @ 2019-09-01 21:27  陈彦斌  阅读(609)  评论(1编辑  收藏  举报