Asp.Net Session详谈

   HTTP 协议之所以能够获得如此大的成功,其设计实现的简洁性和无状态连接的高效率是很重要的原因。而为了在无状态的 HTTP 请求和有状态的客户端操作之间达到平衡,产生了服务器端会话 (Session) 的概念。客户端在连接到服务器后,就由 Web 服务器产生并维护一个客户端的会话;当客户端通过无状态 HTTP 协议再次连接到服务器时,服务器根据客户端提交的某种凭据,如 Cookie 或 URL 参数,将客户关联到某个会话上,这种思路在各种开发语言和开发环境中大量得到应用。

 

而在 ASP.NET 中,因为设计时就考虑了这些问题: 


    1.支持不使用 Cookie 的状态维护,通过在 URL 中自动增加会话 ID 来避免使用 Cookie.

    2.支持进程外的状态管理,通过独立状态管理服务或 SQL Server 状态服务器管理会话状态.

    3.通过独立的状态管理服务或SQL Server 状态服务器支持负载均衡时同步使用会话信息.

 

下面简单说一下Session的会话机制:

Session数据保存在服务器端, 但是每一个客户端都需要保存一个SessionID, SessionID保存在Cookies中, 关闭浏览器时过期.在向服务器发送的HTTP请求中会包含SessionID,

服务器端根据SessionID获取获取此用户的Session信息.当客户端向服务端发生会话时(不是访问了网站某页面就一定产生了会话),服务端会写一个cookie到客户端,这个cookie

保存着sessionid,名字为"ASP.NET_SessionID" ,在下一次发生向服务端的请求时这个cookie会包含在请求头中,这个cookie仅仅包含了sessionid,其他信息以(某种形式)保存在服务端并被sessionid标识。

但是如果浏览器禁用的Cookie,那Asp.Net如何处理呢?

Asp.Net支持URL传输入SessionID,如果Cookie被禁用,SessionID会直接以密文放在URL地址中.这时后台服务器可以通过URL获取SessionID.缺点是不能再使用绝对链接了,如下面的链接:

http://localhost/MyTestApplication/(ulqsek45heu3ic2a5zgdl245) /default.aspx

 

大概介绍完Session的会话机制后,后面分别介绍通过状态管理服务和SQL Server状态服务器以及Memcached来实现跨站Session共享.

 

一、使用 StateServer 模式搭建Session服务器

(1)服务器配置

1.启动 Asp.net State service服务.(这个服务默认的状态为手动.修改为自动并启动.)

2.修改注册表: [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\aspnet_state\Parameters] 设置 AllowRemoteConnection = 1 , 设置 Port = 42424 (十进制,默认即为42424)

Port是服务的端口号

AllowRemoteConnection 表示是否允许其他机器连接,0为仅能本机使用,1为可以供其他机器使用.

(2)客户端配置

1.在Web应用程序的Web.Config中, 我们需要修改<system.web> 的<sessionState>节点.如果没有没有则添加(默认使用的是InProc方式)

<sessionState mode="StateServer" stateConnectionString="tcpip=服务器ip:42424" cookieless="false" timeout="60"/>

上面的参数我们可以根据需要修改.

2.需要让所有机器的MachineKey相同.在Machine.Config中配置:

<machineKey validationKey="1234567890123456789012345678901234567890AAAAAAAAAA"
             decryptionKey="123456789012345678901234567890123456789012345678"
             validation="SHA1"
             decryption="Auto"/>

3. 每台前端WEB服务的Microsoft“Internet 信息服务”(IIS)设置 要在 Web 场中的不同 Web 服务器间维护会话状态,Microsoft Internet 信息服务(IIS) 配置数据库中 Web 站点的应用程序路径(例如\LM\W3SVC\2)与 Web 场中所有 Web 服务器必须相同。大小写也必须相同,因为应用程序路径是区分大小写的。在一台 Web 服务器上,承载 ASP.NET 应用程序的 Web 站点的实例 ID 可能是 2(其中应用程序路径是 \LM\W3SVC\2).在另一台 Web 服务器上,Web 站点的实例 ID 可能是 3(其中应用程序路径是 \LM\W3SVC\3).Web 场中的 Web 服务器之间的应用程序路径是不同的。我们必须使Web 场Web 站点的实例 ID 相同即可。你可以在IIS中把某一个WEB配置信息保存为一个文件,其他Web 服务器的IIS配置可以来自这一个文件.

相关设置以及一些Session的FAQ请看:

http://support.microsoft.com/default.aspx?scid=kb;zh-cn;325056

http://support.microsoft.com/?id=324772

 

二、使用 SqlServer 状态模式搭建Session服务器

1、进行VS2010命令提示cmd窗体,键入命令:aspnet_regsql.exe -sstype c -ssadd -d 你的数据库名 -U 用户名 -P 密码 -S 数据库服务地址

sstype 参数:

选项说明

t: 将会话数据存储到 SQL Server tempdb 数据库中。这是默认设置。如果将会话数据存储到 tempdb 数据库中,则在重新启动 SQL Server 时将丢失会话数据。

p: 将会话数据存储到 ASPState 数据库中,而不是存储到 tempdb 数据库中。

c: 将会话数据存储到自定义数据库中。如果指定 c 选项,则还必须使用 -d 选项包括自定义数据库的名称。

QQ截图20130826093446 

 

2、<sessionState mode="SQLServer" allowCustomSqlDatabase="true" sqlConnectionString="server=127.0.0.1;DataBase=master;uid=sa;pwd=sa1234;"/>

 

3、在数据库中产生两张新表

ASPStateTempApplications: 存储应用程序Id及名称

ASPStateTempSessions: 存储具体的Session值,ASPStateTempSessions 这个表中主键SessionID,

其中的SessionId包括两个部分:网站生成的24位SessionID及8位AppName对于不同的站点,其AppName不同,在能够在不同站点下使24位SessionID相同的情况下,

要保证经过组合加上AppName后的SessionID相同,可以通过修改存储过程TempGetAppID,使其得到的SessionID与AppName无关.

不同的应用程序会在ASPStateTempApplications中注册不同的数据,从而在ASPStateTempSessions中有不同的Session,如果要实现Session共享,

可以用欺骗SqlServer的方法:用某种方法使得不同的应用程序访问数据库时用相同的App!为了达到这个目的,分析[dbo].[TempGetAppID]这个存储过程.

TempGetAppID存储过程代码贴出来:

   ALTER PROCEDURE [dbo].[TempGetAppID]
    @appName    tAppName,
    @appId      int OUTPUT
    AS
    SET @appName = LOWER(@appName)     //把这句改为SET @appName = 'Everything you want' 即能达到不同应用程序使用相同的App.
    SET @appId = NULL

    SELECT @appId = AppId  //或者修改此行代码,SELECT top 1 @appId = AppId
    FROM [master].dbo.ASPStateTempApplications
    WHERE AppName = @appName

    IF @appId IS NULL BEGIN
        BEGIN TRAN       

        SELECT @appId = AppId
        FROM [master].dbo.ASPStateTempApplications WITH (TABLOCKX)
        WHERE AppName = @appName

        IF @appId IS NULL
        BEGIN
            EXEC GetHashCode @appName, @appId OUTPUT
            INSERT [master].dbo.ASPStateTempApplications
            VALUES
            (@appId , @appName)
            IF @@ERROR = 2627
            BEGIN
                DECLARE @dupApp tAppName
                SELECT @dupApp = RTRIM(AppName)
                FROM [master].dbo.ASPStateTempApplications
                WHERE AppId = @appId 

                RAISERROR('SQL session state fatal error: hash-code collision between applications ''%s'' and ''%s''. Please rename the 1st application to resolve the problem.',
                            18, 1, @appName, @dupApp)
            END
        END

        COMMIT
    END

    RETURN 0

备注:在SQLServer模式下,session过期是由SQL Agent使用一个注册任务完成的(本例中是master_Job_DeleteExpiredSessions),要确认SQL Agent已经运行。否则无法清理过期的Session数据, 会导致数据库数据一直增加.

 

三、使用Memcached存储Session

这个不多说了,可以看下下面的文章

http://www.cnblogs.com/mecity/archive/2011/07/02/2096202.html

http://blog.csdn.net/wangpengan/article/details/7744255

 

转载于:https://www.cnblogs.com/tangzhenjie/p/3282461.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值