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

在分布式项目中使用memcached+cookie替代session

2016-01-04 11:29 686 查看
为什么要去session:多服务器不能共享,虽然有进程外session,但是性能很低

session局限性:

1.占用资源高

2.管理不方便

3.跨域、跨主机支持性很麻烦

4.性能差

5.容易产生系统垃圾

6.不稳定性,如:服务器重启后SESSION容易丢失

向客户端保存cookie:Response.Cookies.Add(HttpCookie的对象);

向服务端提交cookie:Request.Cookies[key];

设置属性:Response.Cookies[key].Expired=...;

小问题:这里也需要引入log4net,但是两个程序集的版本是不一致的,为了能够并存,可以到log4net源码中重新生成一个其它名称的程序集,如log4net_log

步骤:

(1)在cookie中存储guid值,每次请求上传这个值

(2)使用客户端对象,根据guid作为键进行查找对象

实例:分布式缓存去session登陆

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using HM13OA.Common;
using HM13OA.UI.Models;

namespace HM13OA.UI.Controllers
{
public class MyBaseController : Controller
{
protected override void OnAuthorization(AuthorizationContext filterContext)
{
//return;
//base.OnAuthorization(filterContext);

//去session,使用分布式缓存完成登录
//if (Session["UserLogin"] == null)
//{
//    filterContext.Result=new RedirectResult(Url.Action("Index","UserLogin"));
//}

//1、获取客户端标识
if (Request.Cookies.Get("loginId") == null)
{
filterContext.Result = new RedirectResult(Url.Action("Index", "UserLogin"));
return;
}
string key=Request.Cookies.Get("loginId").Value;
//2、与分布式缓存进行通信,获取对象
MmHelper helper=new MmHelper();
UserInfoViewModel userInfoViewModel = helper.Get(key) as UserInfoViewModel;
//3、判断是否登录
if (userInfoViewModel == null)
{
filterContext.Result = new RedirectResult(Url.Action("Index", "UserLogin"));
return;
}
//4、设置超时滑动时间
helper.Set(key, userInfoViewModel, DateTime.Now.AddMinutes(20));

}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DotNetOpenAuth.OpenId.Extensions.AttributeExchange;
using HM13OA.Common;
using HM13OA.IService;
using HM13OA.Model;
using HM13OA.UI.Models;

namespace HM13OA.UI.Controllers
{
public class UserLoginController : Controller
{
public IUserInfoService UserInfoService { get; set; }

public ActionResult Index()
{
return View();
}

public ActionResult ValidateCode()
{
ValidateCode vCode = new ValidateCode();
string code = vCode.CreateValidateCode(4);
Session["ValidateCode"] = code;
byte[] bytes = vCode.CreateValidateGraphic(code);
return File(bytes, @"image/jpeg");

}
[HttpPost]
public ActionResult Login(UserInfoViewModel userInfo)
{
string result = "no";

//判断是否是一个正常的请求
if (Session["ValidateCode"] == null || Session["ValidateCode"].ToString() == "")
{
return Content("请正常请求");
}

string vcode = Request["vCode"];
//先匹配验证码
if (Session["ValidateCode"].ToString().Equals(vcode,StringComparison.InvariantCultureIgnoreCase))
{
//根据用户名密码进行查询
if (UserInfoService.Login(new UserInfo()
{
UserName = userInfo.UserName,
UserPwd = userInfo.UserPwd
}))
{
result = "ok";

//去session,改成分布式缓存
//Session["UserLogin"] = userInfo;

//使用分布式缓存进行登录操作
//1、创建标识
string key = Guid.NewGuid().ToString();
//2、向客户端写标识
Response.Cookies.Add(new HttpCookie("loginId",key));
//3、向分布式缓存服务器写信息
MmHelper helper=new MmHelper();
helper.Set(key, userInfo, DateTime.Now.AddMinutes(20));
}
else
{
result = "用户名或密码错误";
Session["ValidateCode"] = "";
}
}
else
{
//验证码不匹配
result = "验证码错误";
Session["ValidateCode"] = "";
}

return Content(result);
}

public ActionResult Logout()
{
//去session
//Session["UserInfo"] = null;

//使用分布式缓存的用户注销
if (Request.Cookies.Get("loginId") != null)
{
string key = Request.Cookies.Get("loginId").Value;
//1、更新客户端cookie
//Response.Cookies["loginId"].Expires = DateTime.Now.AddMinutes(-1);
//2、销毁分布式缓存中的对象
MmHelper helper=new MmHelper();
helper.Delete(key);
}

return RedirectToAction("Index");
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using  Memcached.ClientLibrary;

namespace HM13OA.Common
{
public partial class MmHelper
{
private MemcachedClient client;
public MmHelper()
{
string[] ips = System.Configuration.ConfigurationManager.AppSettings["MemcachedServers"].Split(',');

SockIOPool pool = SockIOPool.GetInstance();
pool.SetServers(ips);
pool.Initialize();

client=new MemcachedClient();
client.EnableCompression = true;
}

public bool Set(string guid,object value,DateTime expiryTime)
{
return client.Set(guid, value, expiryTime);
}

public object Get(string guid)
{
return client.Get(guid);
}

public bool Delete(string guid)
{
return client.Delete(guid);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: