MVC使用Memcache+Cookie解决分布式系统共享登录状态学习笔记6

 更新时间:2021年9月22日 10:06  点击:1892

      为了解决单机处理的瓶颈,增强软件的可用性,我们需要将软件部署在多台服务器上启用多个二级子域名以频道化的方式,根据业务功能将网站分布部署在独立的服务器上,或通过负载均衡技术(如:DNS轮询、Radware、F5、LVS等)让多个频道共享一组服务器。当我们将网站程序分部到多台服务器上后,由于Session受实现原理的局限,无法跨服务器同步更新Session,使得登录状态难以通过Session共享。

      我们使用MemCache+Cookie方案来解决分布式系统共享登录状态的问题。

      Memcache服务器本身就是一个Socket服务端,内部数据采用键值对的形式存储在服务器的内存中,本质就是一个大型的哈希表。数据的删除采用惰性删除机制。虽然Memcache并没有提供集群功能,但是通过客户端的驱动程序很容易就可以实现Memcache的集群配置。

     先简单介绍一下Memcache的用法

1. 下载安装Memcache(Windows平台)

    (1)将程序解压到磁盘任意位置

    (2)进入cmd窗口,运行Memcached.exe -d install安装服务,安装后打开服务窗口查看服务是否安装成功。

    (3)直接在服务管理中启动服务,或者使用cmd命令 net start "Memcache Server"

    (4)使用Telnet连接到Memcache控制台,验证服务是否正常 telnet 127.0.0.1 11211

            使用stats指令查看当前Memcache服务器状态

2. 程序中的用法

    (1)在程序中添加 Memcached.ClientLibrary.dll 的引用

    (2)C#中操作Memcache的代码示例

String[] serverlist = { "192.168.1.100:11211",
"192.168.1.101:11211" };
// initialize the pool for memcache servers
SockIOPool pool = SockIOPool.GetInstance("test");
pool.SetServers(serverlist);
pool.Initialize();
mc = new MemcacheClient();
mc.PoolName = "test";
mc.EnableCompression = false;
pool.Shutdown();//关闭连接池

下面我们做方案的具体实现

1. 首先在Common层中引入Memcached.ClientLibrary.dll,并封装Memcache的帮助类,MemcacheHelper

using Memcached.ClientLibrary;
using System;

namespace PMS.Common
{
 public class MemcacheHelper
 {
 private static readonly MemcachedClient Mc = null;

 static MemcacheHelper()
 {
 //最好放在配置文件中
 string[] serverlist = { "127.0.0.1:11211", "10.0.0.132:11211" };

 //初始化池
 var pool = SockIOPool.GetInstance();
 pool.SetServers(serverlist);

 pool.InitConnections = 3;
 pool.MinConnections = 3;
 pool.MaxConnections = 5;

 pool.SocketConnectTimeout = 1000;
 pool.SocketTimeout = 3000;

 pool.MaintenanceSleep = 30;
 pool.Failover = true;

 pool.Nagle = false;
 pool.Initialize();

 // 获得客户端实例
 Mc = new MemcachedClient {EnableCompression = false};
 }
 /// <summary>
 /// 存储数据
 /// </summary>
 /// <param name="key"></param>
 /// <param name="value"></param>
 /// <returns></returns>
 public static bool Set(string key,object value)
 {
 return Mc.Set(key, value);
 }
 public static bool Set(string key, object value,DateTime time)
 {
 return Mc.Set(key, value,time);
 }
 /// <summary>
 /// 获取数据
 /// </summary>
 /// <param name="key"></param>
 /// <returns></returns>
 public static object Get(string key)
 {
 return Mc.Get(key);
 }
 /// <summary>
 /// 删除
 /// </summary>
 /// <param name="key"></param>
 /// <returns></returns>
 public static bool Delete(string key)
 {
 return Mc.KeyExists(key) && Mc.Delete(key);
 }
 }
}

2. 改变用户登录方法UserLogin,用户登录成功后生成GUID,将此GUID存入Cookie并以GUID为键将登录用户信息序列化存入Memcache服务器。

public ActionResult UserLogin()
{
 #region 验证码校验
 var validateCode = Session["validateCode"] != null ? Session["validateCode"].ToString() : string.Empty;
 if (string.IsNullOrEmpty(validateCode))
 return Content("no:验证码错误!!");
 Session["validateCode"] = null;
 var txtCode = Request["ValidateCode"];
 if (!validateCode.Equals(txtCode, StringComparison.InvariantCultureIgnoreCase))
 return Content("no:验证码错误!!");
 #endregion

 var userName = Request["UserName"];
 var userPwd = Request["PassWord"];
 //查询用户是否存在
 var user = UserService.LoadEntities(u => u.UserName == userName && u.PassWord == userPwd).FirstOrDefault();
 if (user == null) return Content("no:登录失败");

 //产生一个GUID值作为Memache的键.
 var sessionId = Guid.NewGuid().ToString();
 //将登录用户信息存储到Memcache中。
 MemcacheHelper.Set(sessionId, SerializeHelper.SerializeToString(user), DateTime.Now.AddMinutes(20));
 //将Memcache的key以Cookie的形式返回给浏览器。
 Response.Cookies["sessionId"].Value = sessionId;
 return Content("ok:登录成功");
}

3. 改变登录校验控制器FilterController的OnActionExecuting方法,使其校验方式改为从Memcache服务器中读取Cookie中值为键的对象:

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
 base.OnActionExecuting(filterContext);
 //if (Session["user"] == null)
 if (Request.Cookies["sessionId"] != null)
 {
 var sessionId = Request.Cookies["sessionId"].Value;
 //根据该值查Memcache.
 var obj = MemcacheHelper.Get(sessionId);
 if (obj == null)
 {
 filterContext.Result = Redirect("/Login/Index");
 return;
 }
 var user = SerializeHelper.DeserializeToObject<User>(obj.ToString());
 LoginUser = user;
 //模拟出滑动过期时间.
 MemcacheHelper.Set(sessionId, obj, DateTime.Now.AddMinutes(20)); 
 }
 else
 filterContext.Result = Redirect("/Login/Index");
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持猪先飞。

[!--infotagslink--]

相关文章

  • phpems SQL注入(cookies)分析研究

    PHPEMS(PHP Exam Management System)在线模拟考试系统基于PHP+Mysql开发,主要用于搭建模拟考试平台,支持多种题型和展现方式,是国内首款支持题冒题和自动评分与教师评分相...2016-11-25
  • JS使用cookie实现DIV提示框只显示一次的方法

    本文实例讲述了JS使用cookie实现DIV提示框只显示一次的方法。分享给大家供大家参考,具体如下:这里运用JavaScript的cookie技术,控制网页上的提示DIV只显示一次,也就是当用户是第一次打开网页的时候才显示,第二次自动隐藏起...2015-11-08
  • PHP分布式框架如何使用Memcache同步SESSION教程

    本教程主要讲解PHP项目如何用实现memcache分布式,配置使用memcache存储session数据,以及memcache的SESSION数据如何同步。 至于Memcache的安装配置,我们就不讲了,以前...2016-11-25
  • PHP中SSO Cookie登录分析和实现

    什么是SSO?单点登录SSO(Single Sign-On)是身份管理中的一部分。SSO的一种较为通俗的定义是:SSO是指访问同一服务器不同应用中的受保护资源的同一用户,只需要登录一次,即通过一个应用中的安全验证后,再访问其他应用中的受保护...2015-11-08
  • PHP中SSO Cookie登录分析和实现

    什么是SSO?单点登录SSO(Single Sign-On)是身份管理中的一部分。SSO的一种较为通俗的定义是:SSO是指访问同一服务器不同应用中的受保护资源的同一用户,只需要登录一次,即通过一个应用中的安全验证后,再访问其他应用中的受保护...2015-11-08
  • SpringMVC文件上传原理及实现过程解析

    这篇文章主要介绍了SpringMVC文件上传原理及实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-07-15
  • vue项目中js-cookie的使用存储token操作

    这篇文章主要介绍了vue项目中js-cookie的使用存储token操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-11-14
  • C# MVC模式中应该怎样区分应用程序逻辑(Controller层)和业务逻辑(Model层)?

    这篇文章主要介绍了C# MVC模式中应该怎样区分应用程序逻辑(Controller层)和业务逻辑(Model层)?,这也小编做.NET项目时经常思考和让人混乱的一个问题,这篇文章写的挺好,一下清晰了许多,需要的朋友可以参考下...2020-06-25
  • 什么是cookie?js手动创建和存储cookie

    什么是cookie? cookie 是存储于访问者的计算机中的变量。每当同一台计算机通过浏览器请求某个页面时,就会发送这个 cookie。你可以使用 JavaScript 来创建和取回 cookie 的值。 有关cookie的例子: 名字 cookie 当访...2014-05-31
  • PHP+memcache实现消息队列案例分享

    memche消息队列的原理就是在key上做文章,用以做一个连续的数字加上前缀记录序列化以后消息或者日志。然后通过定时程序将内容落地到文件或者数据库。php实现消息队列的用处比如在做发送邮件时发送大量邮件很费时间的问...2014-05-31
  • 使用Maven 搭建 Spring MVC 本地部署Tomcat的详细教程

    这篇文章主要介绍了使用Maven 搭建 Spring MVC 本地部署Tomcat,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-08-16
  • python爬虫用request库处理cookie的实例讲解

    在本篇内容里小编给大家整理的是一篇关于python爬虫用request库处理cookie的实例讲解内容,有需要的朋友们可以学习参考下。...2021-02-21
  • SpringMvc自动装箱及GET请求参数原理解析

    这篇文章主要介绍了SpringMvc自动装箱及GET请求参数原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-19
  • SpringMvc获取请求头请求体消息过程解析

    这篇文章主要介绍了SpringMvc获取请求头请求体消息过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-17
  • Springmvc ResponseBody响应json数据实现过程

    这篇文章主要介绍了Springmvc ResponseBody响应json数据实现过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-10-26
  • 基于C#后台调用跨域MVC服务及带Cookie验证的实现

    本篇文章介绍了,基于C#后台调用跨域MVC服务及带Cookie验证的实现。需要的朋友参考下...2020-06-25
  • 理解javascript中的MVC模式

    这篇文章主要为大家介绍了javascript中的MVC模式,MVC是一种软件架构模式,一般把软件模式分为三部分,本文就针对MVC模式的三部分进行讲解,感兴趣的小伙伴们可以参考一下...2016-02-01
  • Spring MVC 处理一个请求的流程

    Spring MVC是Spring系列框架中使用频率最高的部分。不管是Spring Boot还是传统的Spring项目,只要是Web项目都会使用到Spring MVC部分。因此程序员一定要熟练掌握MVC部分。本篇博客简要分析Spring MVC处理一个请求的流程。...2021-02-06
  • 仅30行代码实现Javascript中的MVC

    这篇文章主要介绍了仅30行代码实现Javascript中的MVC的方法,MVC的基础是观察者模式,这是实现model和view同步的关键,想要深入了解的朋友可以参考本文...2016-02-18
  • 使用jQuery.form.js/springmvc框架实现文件上传功能

    这篇文章主要介绍了使用jQuery.form.jsspringmvc框架实现文件上传功能,非常具有参考借鉴价值,感兴趣的朋友一起学习吧...2016-05-14