zoukankan      html  css  js  c++  java
  • ASP.net 中关于Session的存储信息及其它方式存储信息的讨论与总结

        通过学习和实践笔者总结一下Session 的存储方式。虽然里面的理论众所周知,但是我还是想记录并整理一下。作为备忘录吧。除了ASP.net通过Web.config配置的方式,还有通过其它方式来存储的方案。

    Web.config配置详解如下:

    <sessionState mode="Off|InProc|StateServer|SQLServer"

                  cookieless="true|false"

                  timeout="number of minutes"

                  stateConnectionString="tcpip=server:port"

                  sqlConnectionString="sql connection string"

                  stateNetworkTimeout="number of seconds" />

    上面是Session在Web.config的配置方式,下面对各个节点做一些简单的介绍

    mode(设置将服务器的Session信息存储到哪里)

    • Off表示设置为不使用Session功能;
    • InProc表示将Session存储在进程内,这也是ASP中的存储方式,这是默认值;
    • StateServer表示将Session存储在独立的状态服务即ASP.NET State Service中;
    • SQLServer表示将Session存储在SQL Server。

    cookieless(设置客户端的Session信息存储到哪里)

    • true表示使用Cookieless模式(这表明SessionId将不再使用Cookie存储了,而是将其通过URL存储);
    • false表示使用Cookie模式,这是默认值。

    从上面的设置配置中我们也可以发现Session和Cookie的关系:

    • 首先Session在客户端的实现肯定是SessionId;
    • 默认这个SessionId是通过Cookie存储的(比较安全);
    • 当然也可以通过URL来进行存储,这样Session和Cookie就没有关系了,但是此种方式由于受URL长度限制以及明文传送导致不安全而不被推荐使用。

    timeout

    Session过期时间设置,默认为20分钟。

    stateConnectionString

    如果设置将Session信息存储在State Server中时,则需要此配置字符串表明服务器名称和端口。

    sqlConnectionString

    如果设置将Session信息存储在SQL Server中,需此配置,表明数据库的连接字符串,同时stateNetworkTimeout表明经过多少秒空闲后,断开Web服务器与存储状态信息的服务器的TCP/IP连接的。默认值是10秒钟。

     

    方式A:

    InProc 方式,如上所述,存在进程中, web服务器中,速度快。最大的缺点,也是致命的缺点易丢,特别是虚拟机中,丢失的十分严重,笔者深有体会. IIS重启将会丢失Session。丢失的主要原因是,IIS中存储session的这个进程不稳定,在某些事件发生时,进程会重起,所以造成了存储在该进程内的Session丢失。

    哪些情况下该进程会重起呢?微软的一篇文章告诉了我们:
    1、配置文件中processModel标签的memoryLimit属性
    2、Global.asax或者Web.config文件被更改
    3、Bin文件夹中的Web程序(DLL)被修改
    4、杀毒软件扫描了一些.config文件。

    方式B:

    StateServer方式,存在于Windows服务进程(内存),首先,让我们来打开管理工具(可以是站点的web服务器也可以是其它windows server服务器,但你要能过IP指定)->服务,找到名为:asp.NET State  Service的服务,启动它。注:如果在启动ASP.NET State Service服务时遇到问题0x8007277a 即无法启动或初始化,请尝试在命令行(CMD)中输入netsh winsock reset(有可能是winsock的问题,所以需reset一下)实际上,这个服务就是启动一个要保存session信息的进程。启动这个服务后,你可以从Windows任务管理器->进程中看到一个名为 aspnet_state.exe的进程,这个就是我们保存session信息的进程。
            然后,回到Web.config文件中上述的段落中,将mode的值改为StateServer。

    这种方式不session不会丢失,既使是IIS重启,也不会丢失.

     < sessionState
            mode=" StateServer "
            stateConnectionString="tcpip=127.0.0.1:42424"
            sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes"
            cookieless="false"
            timeout="20"
          />
    实际上,这种将session信息存储在进程外的方式不光指可以将信息存储在本机的进程外,还可以将session信息存储在其他的服务器的进程中。这时,不光需要将mode
    的值改为StateServer,还需要在stateConnectionString中配置相应的参数。例如你的计
    算你是192.168.0.1,你想把session存储在ip为192.168.0.2的计算机的进程中,就需要
    设置成这样:
          stateConnectionString="tcpip=192.168.0.2:42424"。当然,不要忘记在
    192.168.0.2的计算机中装上.NET Framework,并且启动asp.NET State Services服务。

    这种方式,存在Session里的数据必须可序列化,序列化与反序列化消耗CPU资源,而且读取速度与网速有关(存在其它服务器时)。

    [Serializable]

    public class MyClass

    {

        //......

    }

    第一个问题,参见

    ASP.NET Session State Partitioning  
    http://blog.maartenballiauw.be/post/2008/01/23/ASPNET-Session-State-Partitioning.aspx 中的解决方案。其实大概的意思是,创建PartitionResolver : System.Web.IPartitionResolver

    using System;

    public class PartitionResolver : System.Web.IPartitionResolver
    {

        #region Private members

        private String[] partitions;

        #endregion

        #region IPartitionResolver Members

        public void Initialize()
        {
            // Create an array containing
            // all partition connection strings
            //
            // Note that this could also be an array
            // of SQL server connection strings!
            partitions = new String[] {       
                "tcpip=10.0.0.1:42424",    
                "tcpip=10.0.0.2:42424",        
                "tcpip=10.0.0.3:42424"
            };
        }

        public string ResolvePartition(object key)
        {
            // Accept incoming session identifier
            // which looks similar like "2ywbtzez3eqxut45ukyzq3qp"
            string sessionId = key as string;

            // Create your own manner to divide session id's
            // across available partitions or simply use this one!
            int partitionID = Math.Abs(sessionId.GetHashCode()) % partitions.Length;
            return partitions[partitionID];
        }

    #endregion
    }

    Update your web.config

    <configuration>
      <system.web>
        <!-- ... -->
        <sessionState 
            mode="StateServer" 
            partitionResolverType="PartitionResolver" />
        <!-- ... -->
      </system.web>
    </configuration>

    Webconfig中指定你的server类.

    第二个问题:

    参见:

    http://blog.maartenballiauw.be/post/2007/11/22/ASPNET-load-balancing-and-ASPNET-state-server-(aspnet_state).aspx

    修改web.config,就可以解决。为每台webserver的web.config.修改如下

    <configuration>
        <system.web>
            <machineKey 
              validationKey="1234567890123456789012345678901234567890AAAAAAAAAA"
              decryptionKey="123456789012345678901234567890123456789012345678"
              validation="SHA1"
              decryption="Auto"
            />
            <!-- ... -->
            <sessionState
                mode="StateServer"
                stateConnectionString="tcpip=your_server_ip:42424"
                cookieless="false"
                timeout="20" />
            <!-- ... -->
        </system.web>
    </configuration>

    方式C:

    SQL Server方式,

    此种方式是把Session信息保存在SQL Server的数据库中,也需要序列化,性能有较大损失,但是Session一般不会发生丢失的情况,除非SQL Server宕机。而且此种方式也可以实现在Web Farm中的Session信息共享(上面两种方式都不可以)。

    <sessionState mode="SQLServer" sqlConnectionString ="data source=10.7.11.114; user id=lms_session; password=LmsSession@2012" timeout="20" />

    3.1 安装ASPState数据库

    在使用之前,我们要安装配置对应的数据库,而微软给我们提供了一整套方案(你也可以选择使用自己的数据库或自己实现配置和管理)。ASP.NET 2.0版本后微软提供了aspnet_regsql.exe工具可以方便的配置Session数据库,该工具位于 Web 服务器上的"系统根目录Microsoft.NETFramework版本号"文件夹中.

    使用举例:

    aspnet_regsql.exe -S . -U SessionStateUser-P 123456 -ssadd -sstype p

    -S参数:

    表示数据库实例名称. 可以用"."表示本机.

    -U和-P参数:

    表示用户名和密码.

    -E参数:

    可以再-U –P 与 -E中选择一组. –E表示以当前系统用户通过windows身份验证登录数据库, -U -P则是使用SqlServer用户登录数据库.

    -ssadd / –ssremove 参数:

    -ssadd表示是添加Session数据库, -ssremove表示移除Session数据库.

    sstype 参数:

     

    选项

    说明

    t

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

    p

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

    c

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

    注意:如果sstype为t,则在下面的用户权限赋予中要授予对tempdb的dbowner权限,否则将无法操作数据库。

    3.2 建立连接数据库 ASPState 的用户,并为此用户授权

      运行 SQL Server 的企业管理器 → 展开数据库的安全性 → 右击“登录” → 新建“登录” → 输入“名称” → 选择 “SQL Server 身份验证” → 输入“密码” → 指定“数据库” → 点击“数据库访问” → 勾选 “ASPState” → 选中“db_owner”角色 → 点击“确定” → 再一次输入“密码” → 点击“确定” 后即可建立 ASPState 的用户,下面用命令实现:

    --新建数据库帐号 SessionStateUser ,默认登录 ASPState
    EXEC sp_addlogin 'SessionStateUser', '123456', 'ASPState'

    use ASPState --切换 DataBase

    --将 SessionStateUser 授予 db_owner 的权限
    exec sp_adduser 'SessionStateUser', 'SessionUser' ,'db_owner'

    3.3 启动SQL Server Agent

    自动运行Job ASPState_Job_DeleteExpiredSessions删除过期的Session,否则数据库中的数据将一直增长

     

    以上内容参见:

    http://www.csharpwin.com/dotnetspace/13229r9077.shtml

    http://www.cnblogs.com/gossip/archive/2011/02/09/1950218.html

    方式D:

    使用Cookie,尽量不使用Session. 基于cookie的管理方式。从大型网站的设计原则来看,其中有一条就是减少session的使用,能用cookie的尽量用cookie。 考虑用户登录的场景,在web服务器A收到登录的请求时,将登录的信息以加密cookie的方式存在在客户端。

    方式E:

    内存方式,在服务器中Cache中建立保存用信息队列,统一管理,Cache 方案,可以用Micsoft Enterparse Library- Cache方案,也可以自定义static.存储用户信息。这样做,能保证系统中,用户的唯一性,缺点是一但不按操作退出,没有清除用户,将会出现无法登录,只有等Cache超时,或者管理员手工清除。

    方式F:MemedCahe方案

    MemedCahe是一个软件,分成服务器端和客户端两部,服务端提供内存服务,客户端就是.net部需要使用的部分。

    MemedCahe如何安装与使用请参见,下面两个博客的应用。

    http://blog.csdn.net/educast/article/details/6273341

    http://www.cnblogs.com/luminji/archive/2011/08/17/2140804.html

    MemedCahe编码上使用Session方法与其它方式是一样的,操作很简单。只是在配置的上要添加一些xml格式的编码。实际这种方案要比微软的stateserver方案,要节约资源。

    具体使方式见下面两处博文,写的很不错。

    http://www.cnblogs.com/luminji/archive/2011/08/17/2143371.html

    http://www.cnblogs.com/luminji/archive/2011/11/03/2195704.html

    关于Session更多的讨论,见如下博文

    http://www.cnblogs.com/fish-li/archive/2011/07/31/2123191.html

     

     

  • 相关阅读:
    Chapter 03Using SingleRow Functions to Customize Output(03)
    Chapter 03Using SingleRow Functions to Customize Output(01)
    Chapter 04Using Conversion Functions and Conditional ExpressionsNesting Functions
    Chapter 04Using Conversion Functions and Conditional ExpressionsGeneral Functions
    Chapter 11Creating Other Schema Objects Index
    传奇程序员John Carmack 访谈实录 (zz.is2120)
    保持简单纪念丹尼斯里奇(Dennis Ritchie) (zz.is2120.BG57IV3)
    王江民:传奇一生 (zz.is2120)
    2011台湾游日月潭
    2011台湾游星云大师的佛光寺
  • 原文地址:https://www.cnblogs.com/XPChen/p/3605163.html
Copyright © 2011-2022 走看看