分布式应用首先要解决的是跨域的问题,解决session、frame、cookie的跨域是最基本的,然后才是负载均衡和性能优化,上面的不解决就没法往后面进行。上一博客主要是解决了frame跨域的问题,今天来解决session跨域的问题,如何让session共享。其实解决session共享的方案有好多,比如通过数据库像redis、sqlserver,或者用session服务器,今天主要是通过sql server来实现session共享。

一、什么是cookie?

大家平时在登录网页时有一个记住用户名的选项,等下次登录会填充用户名,甚至有的会自动填充用户名和密码,这样就会很方便用户。那它是怎么实现的呢?其实很简单就是通过cookie保存在浏览器中,如下图,这是163.com存在谷歌浏览器中的cookie,用户在浏览器输入url时,浏览器会将该域名下存储的cookie放在http的head中发送到服务器(浏览器不能把其他域名的cookie也发送到服务器,不然这就乱套了,这么多cookie,什么还有重名的,于是乎这就产生了cookie的跨域,关于cookie的跨域请听下文分解。)然后服务器给控件赋值,于是就达到了自动填充的效果。可能会觉得这样不安全,人家能监听到你的cookie信息,比如用户名密码这些,确实,这也是有一定的弊端,有的做的完善的会进行一些加密,但加密也是需要消耗额外的资源的,所以都是有利有弊吧。而且最重要的是浏览器每次请求都会将对应的cookie发送给服务器,服务器又会把cookie响应给客户端,cookie内容多的时候,可想而知,系统就会变慢,所以性能优化有一条就是对cookie优化,性能优化又是一个新的大陆。

二、session和cookie的关系

关于什么是session,对我来说没有十万个为什么也有一二十个。它是怎么来的又是怎么没的,HTTP本身是无状态的,客户端和服务端又是怎么个的眉来眼去的让服务器知道是同一个用户的操作呢?每个用户登录之后都会在服务器保存session["UserName"],那这么多的session["UserName"],怎么确保A用户获取的session["UserName"]就是它本人的,不是其他用户的呢?对于每次请求都会实例化一个session对象,这个session对象有一个sessionId,当用户设置session["UserName"]后,那这个session对象就会存在服务器中,如果session对象中没有那就会被销毁。保存在服务器中之后,响应给浏览器时会把这个session对象对应的sessionid放在cookie中,这样浏览器下次再请求时就会把这个sessionid带上,然后就能根据sessid找到这个session对象了,而不至于找到别的。在下图可以找到sessionID,设置的session["UserName"]放在session对象的keys熟悉中。Mode时InProc模式,就是放在IIS中。

三、Session共享设置

要想共享,多个应用用一份,那就得先把session分离出来,不然怎么做到共享。

1.启动ASP.NET State Service服务

2.在数据库服务器执行sql

sql文件在C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallSqlState.sql,InstallSqlState.sql是注册,UninstallSqlState.sql是取消。执行完之后只是创建了ASPState数据库,并未创建表如下图,还提示我使用aspnet_regsql.exe去install sql session state。以及启动SQLServer Agent.

3.启动SQLServerAgent

4.注册SQL Session State

原本想着直接运行aspnet_regsql.exe注册,但打开之后提示要用命令行,已经提示用此向导创建或配置成员、角色 事件的,对于回话状态用命令行。

于是乎根据提示cmd命令行 aspnet_regsql.exe -?出现下面的使用方法

由于是我在本地的数据库上所以执行的是我本地的数据库服务器的名字:aspnet_regsql.exe -S PC-201611282159 -E -ssadd -sstype p

注册完成之后ASPState数据库就存在了两张表:ASPStateTempApplications,ASPStateTempSessions

从表结构能看出来有appid和appname,这就导致了默认是一个应用一个id和name,那这样是共享不了的,怎么共享呢?其实也比较容易,只需需改下存储过程TempGetAppID中的WHERE AppName = @appName注释掉,然后重启就好了。

四、demo

这里我创建了两个应用,一个是WebForm的,一个是MVC的,在WebForm中设置session,然后在MVC中获取session。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls; namespace WebForm
{
public partial class Index : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Session["UserName"] = "CuiYW";
HttpCookie cookie = new HttpCookie("UserInfo");
Request.Cookies.Add(cookie);
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc; namespace MVC.Controllers
{
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
if (Session["UserName"] != null)
{
ViewBag.UserName = Session["UserName"];
}
return View();
}
}
}

同时要在webconfig的<system.web>中都要配置

<sessionState mode="SQLServer" allowCustomSqlDatabase="true" sqlConnectionString="server=PC-201611282159; database=ASPState;Trusted_Connection=true;"
timeout="" >

先运行WebForm设置session,然后运行MVC,在View中显示ViewBag.UserName.结果是可以获取到,这就意味着实现了共享。

五、总结

上面主要是利用SessionStateMode的SQLServer来实现session共享,这毕竟是微软的,所以具有一定的局限行,只能是sql server。其实session共享可以用其他的数据库,比如redis,而且一般实际应用中也不会只用一台做服务器,最少有一台做备份。还有就是单点登录的方式有好几个,session共享也只是其中一个。这些都会在以后的博客中一一写到。reids实现session、SSO是我最近的重点。之前对于分布式应用可能也没多少实战,可能主要还是懒,用不到就是了解了解看看书,只有理论没有实践,通过这次将WebForm集成到MVC中,算是动手了一下,也让自己学到很多东西。最后想吐槽一下,写博客真不容易,不仅要写还要边写边操作,为了这篇搞了一上午,下午午休之后又开始搞,直接搞到现在。生活不易啊!!!

SessionStateMode之SQL Server共享session的更多相关文章

  1. 使用SQL Server保存Session状态,实现单点登录

    在做一些应用网站时,我们可能会碰到这样一种情况:整个项目是由多个网站组成的,而我们要实现用户从一个站点登录后,跳转到其他网站不需要重复登录,即实现单点登录.目前实现单点登录的技术也有好几种,这篇文章描 ...

  2. .net用SQL Server进行session会话管理

    保存在内存中的session经常由于dll的变动导致丢失.有一种方法可以长期保存session,那就是session的SqlServer模式. ASP.NET允许将会话数据存储到一个数据库服务器中,方 ...

  3. SQL Server blocking session

    select * from sys.sysprocesses where blocked>0; 96被95block住了. dbcc INPUTBUFFER(95) dbcc INPUTBUFF ...

  4. nginx Win下实现简单的负载均衡(2)站点共享Session

    快速目录: 一.nginx Win下实现简单的负载均衡(1)nginx搭建部署 二.nginx Win下实现简单的负载均衡(2)站点共享Session 三.nginx Win下实现简单的负载均衡(3) ...

  5. 自动化安装SQL Server+SP就那么简单

    随着业务.企业规模的日益壮大,DB的数量也在不断增多,配置一台新增DB,从服务器的参数配置,磁盘阵列规划,DB安装部署,DB参数调优等等一列步骤下来,手工操作的效率变得越来越低,因为我负责的数据库近些 ...

  6. SQL Server 得到SPID,唯一的sessionID

    像.net中的session一样,假设能知道了数据库中的sessionID,那全部的操作都能知道了,由于有了这个唯一的身份识别的标识. 能够做的事情有非常多,如:当前哪个用户在做什么操作,在运行什么s ...

  7. SQL Server 磁盘请求超时的833错误原因分析以及解决

    本文出处:http://www.cnblogs.com/wy123/p/6984885.html 最近遇到一个SQL Server服务器响应极度缓慢,并且出现客户端请求报错的情况,在数据库中的erro ...

  8. Microsoft SQL Server Version List [sqlserver 7.0-------sql server 2016]

    http://sqlserverbuilds.blogspot.jp/   What version of SQL Server do I have? This unofficial build ch ...

  9. Microsoft SQL Server Version List(SQL Server 版本)

    原帖地址 What version of SQL Server do I have? This unofficial build chart lists all of the known Servic ...

随机推荐

  1. EF 数据库迁移(Migration)

    Update-Database -ConnectionStringName "MyConnectionString"

  2. Python基础学习 -- 列表与元组

    本节学习目的: 掌握数据结构中的列表和元组 应用场景: 编程 = 算法 + 数据结构 数据结构: 通过某种方式(例如对元素进行编号)组织在一起的数据元素的集合,这些元素可以是数字或者字符,或者其他数据 ...

  3. 8. leetcode 485. Max Consecutive Ones

    Given a binary array, find the maximum number of consecutive 1s in this array. Example 1: Input: [1, ...

  4. null == undefined ?

    最近在看<JavaScript高级程序设计>一书,书中讲到相等操作符(==)时说,要比较相等性之前,不能将 null 和 undefined 转换成其他任何值,但要记住 null == u ...

  5. 国内阿里Maven仓库镜像及自己收集镜像库

    国内阿里Maven仓库镜像Maven配置文件Maven仓库速度快   国内连接maven官方的仓库更新依赖库,网速一般很慢,收集一些国内快速的maven仓库镜像以备用. 最新更新:2016年11月11 ...

  6. Exceptionless 本地部署踩坑记录

    仅已此文记录 Exceptionless 本地部署所遇到的问题 1.安装ElasticSearch文本 执行elasticsearch目录中的elasticsearch.bat 没有执行成功. 使用命 ...

  7. 再学ajax--第一天

    今天写这个帖子就是是前几天在学ES6在学到Promise实现AJAX操作时,发现对ajax的一些知识点有些遗忘,所以就回头重新复习了一遍ajax,温故而知新. 主要有从4个方面去复习ajax,分析不透 ...

  8. C++ 开发OCX 的方法和注意事项

    C++ 开发OCX 的方法和注意事项 前言 ActiveX控件是一种实现了一系列特定接口而使其在使用和外观上更象一个控件的COM组件.ActiveX控件这种技术涉及到了几乎所有的COM和OLE的技术精 ...

  9. Linux下MySQL安装和配置

    --Linux下MySQL安装和配置 ---------------------------2014/05/18 Linux下MySQL的配置和安装 本文的安装采用 rpm 包安装 1.首先在官网下载 ...

  10. lumen的自定义依赖注入

    比如我现在有个token认证系统,目前我用mysql的token表实现,将来有可能会改成redis,怎么实现未来的无缝连接呢. 先定义一个合约文件app/Contracts/TokenHandler. ...