您的位置:首页 > 数据库 > Memcache

.Net 基于Memcache集群的分布式Session

2019-09-01 21:27 1486 查看

简述

  基于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架构):

登陆页控制器

IBllSession bllSession = BllSessionFactory.GetCurrentBllSession(); //业务层基类
/// <summary>
/// 处理登陆的表单
/// </summary>
/// <returns></returns>
public ActionResult ProcessLogin()
{
try
{
string user_name = Request["LoginId"]; //用户名
string user_pwd = Request["LoginPwd"]; //密码
UserInfo model = new UserInfo(); //实体类
model.UName = user_name; //实体类赋值
model.UPwd = user_pwd;
if (bllSession.UserInfo.Select(model).Count > 0) //判断用户名密码是否正确
{
//旧方法
//Session["loginUser"] = user_name;

//新方法
//Memcache+Cookie替代Session登陆
//立即分配一个标志GUID,把标志作为Memcache存储数据的key,把用户对象放到Memcache,把GUID写到客户端cookie里面去
string userLoginId = Guid.NewGuid().ToString(); //生成一个随机GUID
//将用户的数据写入Memcache
MemcacheHelper.AddCache(userLoginId, user_name, DateTime.Now.AddMinutes(20)); //Memcache帮助类
//往客户端写入Cookie
Response.Cookies["userLoginId"].Value= userLoginId; //将GUID写入Cookie
return Content("ok");
}
else
{
return Content("用户名或密码错误!你会登陆吗?");
}
}
catch (Exception ex)
{
throw ex;
}
}

过滤器基类(判断用户是否登陆)

using Sam.OA.Common;
using System;
using System.Web.Mvc;

namespace Sam.OA.WEBAPP.Controllers
{
/// <summary>
/// 控制器基类帮助类
/// 作者:陈彦斌
/// 更新时间:2019年9月1日17:43:10
/// </summary>
public class BaseController:Controller
{
public bool IsCheckedUserLogin = true;
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
//校验用户是否已登录
if (IsCheckedUserLogin )
{
//新方法
//使用Memcache+Cookie代替Session
if (Request.Cookies["userLoginId"] == null)
{
filterContext.HttpContext.Response.Redirect("/UserLogin/Index");
return;
}
string userGuid = Request.Cookies["userLoginId"].Value; //拿到用户的GUID
object obj = MemcacheHelper.GetCache(userGuid);
if (obj == null || obj.ToString() == "")
{
//用户长时间不操作,超时
filterContext.HttpContext.Response.Redirect("/UserLogin/Index");
}
//滑动窗口机制
MemcacheHelper.SetCache(userGuid, obj, DateTime.Now.AddMinutes(20));

//旧方法Session
//if (filterContext.HttpContext.Session["loginUser"] == null)
//{
//    filterContext.HttpContext.Response.Redirect("/UserLogin/Index");
//}
}
}
}
}

 Memcache帮助类(MemcacheHelper.cs)

using Memcached.ClientLibrary;
using System;

namespace Sam.OA.Common
{
/// <summary>
/// Memcache缓存帮助类
/// 作者:陈彦斌
/// 时间:2019年9月1日15:48:12
/// </summary>
public sealed class MemcacheHelper
{
private static MemcachedClient memcachedClient;
static MemcacheHelper()
{
//分布式Memcached服务器ip 端口
string strAppMemcached = DbUtil.memcacheServiceList;
if (strAppMemcached==""|| strAppMemcached==null)
{
throw new Exception("Memcache远程服务器Ip和端口未配置");
}
string[] servers = strAppMemcached.Split(','); //Memcache机器IP
//初始化池
SockIOPool pool = SockIOPool.GetInstance();
pool.SetServers(servers); //关联连接池
pool.InitConnections = 3; //初始化链接
pool.MinConnections = 3; //最小连接数
pool.MaxConnections = 5; //最大连接数
pool.SocketConnectTimeout = 1000; //Socket超时连接时间
pool.SocketTimeout = 3000; //Socket超时时间
pool.MaintenanceSleep = 30; //Socket休眠时间
pool.Failover = true;
pool.Nagle = false;
pool.Initialize(); //初始化
//客户端实例
if (memcachedClient == null)
{
memcachedClient = new MemcachedClient();
}
memcachedClient.EnableCompression = false; //启动压缩
}
/// <summary>
/// 获取Memcache缓存数据
/// </summary>
/// <param name="CacheKey">键</param>
/// <returns></returns>
public static object GetCache(string CacheKey)
{
return memcachedClient.Get(CacheKey);
}
/// <summary>
/// 设置Memcache缓存数据
/// </summary>
/// <param name="CacheKey">键</param>
/// <param name="CacheValue">值</param>
public static void AddCache(string CacheKey, object CacheValue)
{
memcachedClient.Add(CacheKey, CacheValue);
}
/// <summary>
/// 设置Memcache缓存数据
/// </summary>
/// <param name="CacheKey">键</param>
/// <param name="CacheValue">值</param>
/// <param name="expDate">过期时间</param>
public static void AddCache(string CacheKey, object CacheValue, DateTime expDate)
{
memcachedClient.Add(CacheKey, CacheValue,expDate);
}
/// <summary>
/// 设置Memcache缓存数据,key存在则更新,否则新增
/// </summary>
/// <param name="CacheKey">键</param>
/// <param name="CacheValue">值</param>
public static void SetCache(string CacheKey, object CacheValue)
{
memcachedClient.Set(CacheKey, CacheValue);
}
/// <summary>
/// 设置Memcache缓存数据,key存在则更新,否则新增
/// </summary>
/// <param name="CacheKey">键</param>
/// <param name="CacheValue">值</param>
/// <param name="expDate">过期时间</param>
public static void SetCache(string CacheKey, object CacheValue, DateTime expDate)
{
memcachedClient.Set(CacheKey, CacheValue, expDate);
}
}
}

 觉得对你有帮助的话,帮忙推荐下,还有不懂的地方,欢迎下方留言,明天继续更新Redis!~~

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: