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

为什么要去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);
        }
    }
}



你可能感兴趣的:(在分布式项目中使用memcached+cookie替代session)