65.9K
CodeProject 正在变化。 阅读更多。
Home

探索 ASP.NET 中的会话

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.91/5 (625投票s)

2009年1月15日

CPOL

28分钟阅读

viewsIcon

2573267

downloadIcon

12754

本文介绍了 ASP.NET 2.0 中的会话。不同类型的会话及其配置。还介绍了 Web 场、负载均衡器和 Web 园场景中的会话。

目录

引言

首先,我要感谢所有阅读并投票给我的文章的读者。在初学者指南系列中,我写了一些关于状态管理的文章。这可能是我关于状态管理的最后一篇文章。

本文将让您对会话有一个很好的理解。在本文中,我涵盖了会话的基础知识、存储会话对象的不同方式、Web 场场景中的会话行为、负载均衡器上的会话等。我还详细解释了实时生产环境中的会话行为。希望您会喜欢这篇文章并提供宝贵的建议和反馈。

什么是会话?

Web 是 **无状态的**,这意味着每次页面发布到服务器时都会重新创建一个网页类的新实例。众所周知,HTTP 是一种无状态协议,它无法在页面上保存客户端信息。如果用户插入一些信息并移动到下一页,这些数据将丢失,用户将无法检索这些信息。我们这里需要什么?我们需要存储信息。会话提供了一种在服务器内存中存储信息的设施。它可以支持存储任何类型的对象以及我们自己的自定义对象。对于每个客户端,会话数据都单独存储,这意味着会话数据是按客户端存储的。请看下图

explor2.jpg

图:对于每个客户端,会话数据都单独存储

使用会话进行状态管理是 ASP.NET 最好的功能之一,因为它安全、对用户透明,并且我们可以在其中存储任何类型的对象。除了这些优点,有时会话在高流量站点中可能会导致性能问题,因为它存储在服务器内存中,并且客户端从服务器读取数据。现在让我们看看在我们的 Web 应用程序中使用会话的优点和缺点。

会话的优点和缺点?

以下是使用会话的基本优点和缺点。我将在稍后详细描述每种类型的会话。

优点

  • 它有助于在整个应用程序中维护用户状态和数据。
  • 它易于实现,并且我们可以存储任何类型的对象。
  • 单独存储客户端数据。
  • 会话安全且对用户透明。

缺点

  • 在数据/用户量大的情况下存在性能开销,因为会话数据存储在服务器内存中。
  • 涉及会话数据序列化和反序列化的开销,因为在 StateServerSQLServer 会话模式下,我们需要在存储对象之前对其进行序列化。

除此之外,会话还有许多优点和缺点,这些都基于会话类型。我已在下面的相应部分讨论了所有这些内容。

从会话存储和检索值

在会话中存储和检索值与在 ViewState 中非常相似。我们可以使用 System.Web.SessionState.HttpSessionState 类与会话状态交互,因为它提供了 ASP.NET 页面中的内置会话对象。

以下代码用于将会话值存储到会话中

//Storing UserName in Session
Session["UserName"] = txtUser.Text;

现在,让我们看看如何从会话中检索值

//Check weather session variable null or not
if (Session["UserName"] != null)
{
    //Retrieving UserName from Session
    lblWelcome.Text = "Welcome : " + Session["UserName"];
}
else
{
 //Do Something else
}

我们还可以将会话中存储其他对象。以下示例展示了如何将会话中存储 DataSet

//Storing dataset on Session
Session["DataSet"] = _objDataSet;

以下代码显示了如何从会话中检索该 DataSet

//Check weather session variable null or not
if (Session["DataSet"] != null)
{
    //Retrieving UserName from Session
    DataSet _MyDs = (DataSet)Session["DataSet"];
}
else
{
    //Do Something else
}

参考文献

会话 ID

ASP.NET 使用 120 位标识符来跟踪每个会话。这足够安全,无法逆向工程。当客户端与服务器通信时,只有会话 ID 在它们之间传输。当客户端请求数据时,ASP.NET 查找会话 ID 并检索相应的数据。这通过以下步骤完成

  • 客户端访问网站,信息存储在会话中。
  • 服务器为该客户端创建唯一的会话 ID,并将其存储在会话状态提供程序中。
  • 客户端使用唯一的会话 ID 从服务器请求一些信息。
  • 服务器在会话提供程序中查找并从状态服务器检索序列化数据并进行对象类型转换。

看看图示流程

图:客户端、Web 服务器和状态提供程序的通信

参考文献

会话模式和状态提供程序

在 ASP.NET 中,有以下会话模式可用

  • InProc
  • StateServer
  • SQLServer
  • 自定义

对于每个会话状态,都有一个会话提供程序。下图将向您展示它们之间的关系

图:会话状态架构

我们可以根据我们选择的会话状态来选择会话状态提供程序。当 ASP.NET 根据会话 ID 请求信息时,会话状态及其相应的提供程序负责发送正确的信息。下表显示了会话模式以及提供程序名称

会话状态模式 状态提供程序
InProc 内存对象
StateServer Aspnet_state.exe
SQLServer 数据库
自定义 自定义提供程序

除此之外,还有另一种模式 **Off**。如果我们选择此选项,应用程序的会话将被禁用。但我们的目标是使用会话,因此我们将查看上述四种会话状态模式。

会话状态

会话状态本质上是指您为维护会话而为 Web 应用程序所做的所有设置。会话状态本身就是一件大事。它说明了您所有会话配置,无论是在 *web.config* 中还是来自代码隐藏。在 *web.config* 中,<SessionState> 元素用于设置会话的配置。其中一些是 ModeTimeoutStateConnectionStringCustomProvider 等。我已详细讨论了连接字符串的每个部分。在我讨论会话模式之前,先简要概述一下会话事件。

会话事件

ASP.NET 中有两种会话事件可用

  • Session_Start
  • Session_End

您可以在 Web 应用程序的 *global.asax* 文件中处理这两个事件。当新会话启动时,会触发 session_start 事件,当会话中止或过期时,会触发 Session_End 事件。

void Session_Start(object sender, EventArgs e) 
{
    // Code that runs when a new session is started
}

void Session_End(object sender, EventArgs e) 
{
    // Code that runs when a session ends. 
}

参考文献

会话模式

我已经讨论了 ASP.NET 中的会话模式。以下是 ASP.NET 中可用的不同类型的会话模式

  • 关闭
  • InProc
  • StateServer
  • SQLServer
  • 自定义

如果我们在 *web.config* 中将会话 Mode="off" 设置为“关闭”,则应用程序中的会话将被禁用。为此,我们需要按以下方式配置 *web.config*

InProc 会话模式

这是 ASP.NET 中的默认会话模式。它将会话信息存储在当前应用程序域中。这是 Web 应用程序性能的最佳会话模式。但主要缺点是,如果重新启动服务器,它将丢失数据。InProc 会话模式还有一些优点和缺点。我稍后会讨论这些点。

InProc 会话模式概述

正如我之前讨论的,在 InProc 模式下,会话数据将存储在当前应用程序域中。因此,它易于快速可用。

InProc 会话模式将其会话数据存储在应用程序域上的内存对象中。这由应用程序池中的工作进程处理。因此,如果重新启动服务器,我们将丢失会话数据。如果客户端请求数据,状态提供程序会从内存对象中读取数据并将其返回给客户端。在 *web.config* 中,我们必须指定会话模式并设置超时。

explor3.gif

上述会话超时设置将会话保持活动状态 30 分钟。这也可以通过代码隐藏进行配置。

Session.TimeOut=30;

ASP.NET 中有两种类型的会话事件:Session_Start()Session_End,这是唯一支持 Session_End() 事件的模式。此事件在会话超时期限结束后调用。InProc 会话状态的通用流程如下所示

何时调用 Session_End() 取决于会话超时。这是一种非常快速的机制,因为存储和检索数据时没有发生序列化,并且数据保留在同一个应用程序域中。

何时应使用 InProc 会话模式?

InProc 是默认的会话模式。它对于小型网站和用户数量很少的网站非常有用。我们应该避免在 Web 园场景中使用 InProc(我稍后会讨论这个主题)。

优点和缺点

优点
  • 它将会话数据存储在当前应用程序域的内存对象中。因此,访问数据非常快,并且数据易于获取。
  • 在 InProc 会话模式下存储数据不需要序列化。
  • 实现非常容易,类似于使用 ViewState。
缺点

尽管 InProc 会话是最快、最常用且默认的机制,但它有很多限制

  • 如果工作进程或应用程序域被回收,所有会话数据将丢失。
  • 虽然它最快,但更多的会话数据和更多的用户可能会因为内存使用而影响性能。
  • 我们不能在 Web 园场景中使用它。
  • 此会话模式不适用于 Web 场场景。

根据上述讨论,我们可以得出结论,InProc 是一种非常快速的会话存储机制,但仅适用于小型 Web 应用程序。如果重新启动服务器,或者应用程序域被回收,InProc 会话数据将丢失。它也不适用于 Web 场和 Web 园场景。

现在我们将看看可用来克服这些问题的其他选项。首先是 StateServer 模式。

StateServer 会话模式

StateServer 会话模式概述

这也被称为 Out-Proc 会话模式。StateServer 使用一个独立的 Windows 服务,它独立于 IIS,也可以在单独的服务器上运行。此会话状态完全由 *aspnet_state.exe* 管理。此服务器可能在同一系统上运行,但它位于运行 Web 应用程序的主应用程序域之外。这意味着如果重新启动 ASP.NET 进程,会话数据仍将存在。这种方法由于涉及序列化和反序列化的开销而存在一些缺点,它还增加了数据访问的成本,因为每次用户检索会话数据时,我们的应用程序都会命中不同的进程。

StateServer 会话模式的配置

在 StateServer 模式下,会话数据存储在独立于 IIS 的单独服务器中,并由 *aspnet_state.exe* 处理。此进程作为 Windows 服务运行。您可以从 Windows MMC 或命令提示符启动此服务。

默认情况下,ASP.NET 状态服务的“启动类型”设置为手动;我们必须将其设置为自动。

从命令提示符,只需键入“net start aspnet_state”。默认情况下,此服务侦听 TCP 端口 42424,但我们可以从注册表编辑器更改端口,如下图所示

现在看看 StateServer 设置的 *web.config* 配置。对于 StateServer 设置,我们需要指定 stateConnectionString。这将标识运行状态服务器的系统。默认情况下,stateConnectionString 使用 IP 127.0.0.1 (localhost) 和端口 42424。

explor9.gif

当我们使用 StateServer 时,我们可以配置 stateNetworkTimeOut 属性来指定在取消请求之前等待服务响应的最大秒数。默认超时值为 10 秒。

explor10.gif

要使用 StateServer,我们要存储的对象应该被序列化,并且在检索时,我们需要将其反序列化回来。我已在下面用一个例子描述了这一点。

StateServer 会话模式的工作原理

我们使用 StateServer 会话模式来避免在重新启动 Web 服务器时不必要的会话数据丢失。StateServer 由 *aspnet_state.exe* 进程作为 Windows 服务维护。此进程维护所有会话数据。但我们需要在将数据存储在 StateServer 会话模式中之前对其进行序列化。

如上图所示,当客户端向 Web 服务器发送请求时,Web 服务器将会话数据存储在状态服务器上。StateServer 可以是当前系统,也可以是不同的系统。但它将完全独立于 IIS。StateServer 的目的地将取决于 *web.config* stateConnectionString 设置。如果将其设置为 127.0.0.1:42424,它会将数据存储在本地系统本身。要更改 StateServer 目的地,我们需要更改 IP,并确保 *aspnet_state.exe* 在该系统上正常运行。否则,在尝试将会话数据存储到会话时,您将收到以下异常。

当我们将对象存储在会话中时,它应该被序列化。这些数据将使用状态提供程序存储在 StateServer 系统中。在检索数据时,状态提供程序将返回数据。完整的流程如下图所示

StateServer 会话模式示例

这是一个使用 StateServer 会话模式的简单示例。我直接在 IIS 上创建了这个示例 Web 应用程序,以便我们更容易理解其用法。

步骤 1:打开 Visual Studio > 文件 > 新建 > 网站。选择位置为 HTTP 并创建 Web 应用程序。

现在,如果您打开 IIS,您将看到一个以您的 Web 应用程序名称创建的虚拟目录,在我的例子中是 *StateServer*。

步骤 2:创建一个简单的 UI,用于输入学生的学号和姓名。我们将把姓名和学号存储在状态服务器会话中。我还创建了一个 StudentInfo 类。该类如下所示

[Serializable]
public class StudentInfo
{
    //Default Constructor
    public StudentInfo()
    {
       
    }
    /// <summary>
    /// Create object of student Class
    /// </summary>
    /// <param name="intRoll">Int RollNumber</param>
    /// <param name="strName">String Name</param>
    public StudentInfo(int intRoll, string strName)
    {
        this.Roll = intRoll;
        this.Name = strName;
    }

    private int intRoll;
    private string strName;
    public int Roll
    {
        get
        {
            return intRoll;
        }
        set
        {
            intRoll = value;
        }
    }

    public string Name
    {
        get
        {
            return strName;
        }
        set
        {
            strName = value;
        }
    }
}

现在看看代码隐藏。我添加了两个按钮:一个用于存储会话,另一个用于检索会话。

protected void btnSubmit_Click(object sender, EventArgs e)
{
    StudentInfo _objStudentInfo = 
      new StudentInfo(Int32.Parse( txtRoll.Text) ,txtUserName.Text);
    Session["objStudentInfo"] = _objStudentInfo;
    ResetField();
}
protected void btnRestore_Click(object sender, EventArgs e)
{
    StudentInfo _objStudentInfo = (StudentInfo) Session["objStudentInfo"];
    txtRoll.Text = _objStudentInfo.Roll.ToString();
    txtUserName.Text = _objStudentInfo.Name;
}

步骤 3:按照我之前解释的方式配置您的 *web.config* 以用于状态服务器。并请确保 *aspnet_state.exe* 在配置的服务器上正常运行。

步骤 4:运行应用程序。

输入数据,点击提交。

我做了以下测试,这将完全解释 StateServer 的确切用途。

第一:从 StudentInfo 类中删除 [Serializable] 关键字,然后尝试运行应用程序。当您单击“提交”按钮时,您将收到以下错误

这清楚地表明您必须在存储对象之前对其进行序列化。

第二:运行应用程序,单击“提交”按钮存储数据。重新启动 IIS。

在 InProc 的情况下,您已经丢失了会话数据,但使用 StateServer,单击“恢复会话”,您将获得原始数据,因为 StateServer 数据不依赖于 IIS。它会单独保存。

第三:从 Windows Services MMC 中停止 *aspnet_state.exe* 并提交数据。您将收到以下错误

因为您的状态服务器进程没有运行。因此,在使用 StateServer 模式时请牢记这三点。

优点和缺点

根据上述讨论

优点
  • 它将数据与 IIS 分开,因此 IIS 的任何问题都不会损害会话数据。
  • 它在 Web 场和 Web 园场景中很有用。
缺点
  • 由于序列化和反序列化,过程很慢。
  • 状态服务器始终需要启动并运行。

StateServer 到此为止,您将在负载均衡器、Web 场和 Web 园部分找到更多有趣的观点。

参考文献

SQLServer 会话模式

SQL Server 会话模式概述

这种会话模式在 ASP.NET 中为我们提供了更安全可靠的会话管理。在这种会话模式下,会话数据被序列化并存储在 SQL Server 数据库中。这种会话存储方法的主要缺点是与数据序列化和反序列化相关的开销。尽管如此,它仍然是 Web 场中使用的最佳选择。

要设置 SQL Server,我们需要这些 SQL 脚本

  • 用于安装:*InstallSqlState.sql*
  • 用于卸载:*UninstallSQLState.sql*

配置 SQL Server 最简单的方法是使用 *aspnet_regsql* 命令。

我已在配置部分详细解释了这些文件的使用。这是 Web 场场景中最有用的状态管理。

何时应使用 SQLServer 会话模式?

  • SQL Server 会话模式是一种更可靠、更安全的会话状态管理。
  • 它将数据保存在集中位置(数据库)。
  • 当我们需要以更高的安全性实现会话时,我们应该使用 SQLServer 会话模式。
  • 如果服务器经常重新启动,这是一个理想的选择。
  • 这是 Web 场和 Web 园场景的完美模式(我稍后会详细解释)。
  • 当我们需要在两个不同的应用程序之间共享会话时,我们可以使用 SQLServer 会话模式。

SQLServer 会话模式配置

在 SQLServer 会话模式下,我们将会话数据存储在 SQL Server 中,因此我们首先需要在 *web.config* 中提供数据库连接字符串。sqlConnectionString 属性用于此目的。

设置连接字符串后,我们需要配置 SQL Server。现在我将解释如何使用 *aspnet_regsql* 命令配置您的 SQL Server。

步骤 1:从命令提示符,转到您的 Framework 版本目录。例如:*c:\windows\microsoft.net\framework\<version>*。

步骤 2:使用以下参数运行 *aspnet_regsql* 命令

查看参数及其用法

参数 描述
-ssadd 添加对 SQLServer 模式会话状态的支持。
-sstype p P 代表持久化。它将会话数据持久化到服务器。
-S 服务器名称。
-U 用户名。
-P 密码。

运行命令后,您将收到以下消息

就是这样。

步骤 3:打开 SQL Server Management Studio,检查是否已创建新数据库 ASPState,并且应该有两个表

  • ASPStateTempApplications
  • ASPStateTempSessions

更改 StateServer 示例的配置字符串并运行相同的示例应用程序。

只需存储学号和用户名,然后单击“提交”按钮。从 SQL Server Management Studio 打开 *ASPStateTempSessions* 表... 这是您的会话数据

现在执行我已经在 StateServer 模式部分解释过的以下测试

  1. StydentInfo 类中删除 Serialize 关键字
  2. 重置 IIS 并单击“恢复会话”
  3. 停止 SQL Server 服务

我想我已经很好地解释了 SQLServer 会话模式。

优点和缺点

优点
  • 如果重新启动 IIS,会话数据不受影响。
  • 最可靠和安全的会话管理。
  • 它将数据集中存储,可以轻松地从其他应用程序访问。
  • 在 Web 场和 Web 园场景中非常有用。
缺点
  • 处理速度非常慢。
  • 对象序列化和反序列化会给应用程序带来开销。
  • 由于会话数据在不同的服务器中处理,我们必须注意 SQL Server。它应该始终启动并运行。

参考文献

自定义会话模式

自定义会话模式概述

我们通常使用 InProc、StateServer 或 SQLServer 会话模式来处理我们的应用程序,但我们也需要了解自定义会话模式的基本原理。这种会话模式非常有趣,因为自定义会话赋予我们完全的控制权来创建所有内容,甚至包括会话 ID。您可以编写自己的算法来生成会话 ID。

您可以简单地通过派生自 SessionStateStoreProviderBase 类来实现在其他存储机制中存储会话数据的自定义提供程序。您还可以通过实现 ISessionIDManager 来生成新的会话 ID。

以下是在实现自定义会话期间调用的方法

Initialize 方法中,我们可以设置一个自定义提供程序。这将初始化与该提供程序的连接。SetItemExpireCallback 用于设置 SessionTimeOut。我们可以注册一个在会话过期时将被调用的方法。InitializeRequest 在每个请求上调用,CreateNewStoreData 用于创建 SessionStateStoreData 的新实例。

何时应使用自定义会话模式?

我们可以在以下情况下使用自定义会话模式

  • 我们希望将会话数据存储在 SQL Server 以外的地方。
  • 当我们需要使用现有表来存储会话数据时。
  • 当我们需要创建自己的会话 ID 时。

我们需要哪些配置?

我们需要像这样配置我们的 *web.config*

如果您想了解更多信息,请查看“参考”部分。

优点和缺点

优点
  • 我们可以使用现有表来存储会话数据。这在我们需要使用现有数据库时很有用。
  • 它不依赖于 IIS,因此重新启动 Web 服务器不会对会话数据产生任何影响。
  • 我们可以创建自己的算法来生成会话 ID。
缺点
  • 数据处理速度非常慢。
  • 创建自定义状态提供程序是一项低级任务,需要小心处理以确保安全性。

始终建议使用第三方提供程序而不是创建自己的提供程序。

参考文献

生产部署概述

生产环境是我们将在实时生产服务器上部署应用程序的地方。对于 Web 开发人员来说,在实时服务器上部署应用程序是一个重大的挑战,因为在大型生产环境中,用户数量众多,单个服务器很难处理如此多用户的负载。Web 场、负载均衡器和 Web 园等概念应运而生。

就在几个月前,我在一个实时生产环境中部署了一个 Web 应用程序,该应用程序由数百万用户访问,有超过 10 个 Active Directory 实例,超过 10 个通过负载均衡器连接的 Web 服务器,以及多个数据库服务器、Exchange Server、LCS Server 等。多服务器涉及的主要风险是会话管理。下图显示了生产环境的通用图表

我将尝试解释在部署应用程序时需要牢记的不同场景。

应用程序池

这是在生产环境中为您的应用程序创建的最重要的事物之一。应用程序池用于隔离 IIS 工作进程集,这些工作进程共享相同的配置。应用程序池使我们能够隔离我们的 Web 应用程序,以提高安全性、可靠性和可用性。工作进程充当将每个应用程序池分隔开的进程边界,因此当一个工作进程或应用程序出现问题或被回收时,其他应用程序或工作进程不会受到影响。

应用程序池的标识

应用程序池标识配置是 IIS 6.0 和 IIS 7.0 中安全性的一个重要方面,因为它决定了工作进程在访问资源时的标识。在 IIS 7.0 中,有三个预定义的标识与 IIS 6.0 相同。

应用程序池标识 描述
本地系统

内置帐户,在服务器上具有管理权限。它可以访问本地和远程资源。对于任何访问服务器文件或资源的操作,我们都必须将应用程序池的标识设置为 LocalSystem

本地服务 内置帐户,具有经过身份验证的本地用户帐户的权限。它没有网络访问权限。
网络服务 这是应用程序池的默认标识。NetworkServices 具有经过身份验证的本地用户帐户的权限。

创建和分配应用程序池

打开 IIS 控制台,右键单击应用程序池文件夹 > 创建新。

输入应用程序池 ID,然后单击确定。

现在,右键单击虚拟目录(我正在使用 StateServer 网站),并将 StateServerAppPool 分配给 StateServer 虚拟目录。

因此,此 StateServer 网站将独立运行,并使用 StateServerAppPool。与其他应用程序相关的任何问题都不会影响此应用程序。这是单独创建应用程序池的主要优势。

Web 园

默认情况下,每个应用程序池都使用单个工作进程(*W3Wp.exe*)运行。我们可以为单个应用程序池分配多个工作进程。具有多个工作进程的应用程序池称为 Web 园。具有相同应用程序池的许多工作进程有时可以提供更好的吞吐量性能和应用程序响应时间。每个工作进程都应该有自己的线程和内存空间。

如图片所示,在 IIS 中,可能存在多个应用程序池,每个应用程序池至少有一个工作进程。Web 园应该包含多个工作进程。

在 Web 应用程序中使用 Web 园存在某些限制。如果我们使用 InProc 会话模式,我们的应用程序将无法正常工作,因为会话将由不同的工作进程处理。为了避免这个问题,我们应该使用 OutProc 会话模式,并且我们可以使用会话状态服务器或 SQL-Server 会话状态。

主要优点:Web 园中的工作进程共享到达该特定应用程序池的请求。如果一个工作进程失败,另一个工作进程可以继续处理请求。

如何创建 Web 园?

右键单击应用程序池 > 转到性能选项卡 > 检查 Web 园部分(图片中突出显示)

默认情况下是 1。只需将其更改为大于 1。

会话如何依赖于 Web 园?

我已经解释过 InProc 是由工作进程处理的。它将数据保存在其内存对象中。现在,如果我们有多个工作进程,那么处理会话将非常困难,因为每个工作进程都有自己的内存,所以如果我的第一个请求发送到 WP1 并且它保存了我的会话数据,而第二个请求发送到 WP2,我正在尝试检索会话数据,但它将不可用,这将引发错误。所以请避免在 InProc 会话模式下使用 Web 园。

我们可以在 Web 园中使用 StateServer 或 SQLServer 会话模式,因为正如我之前解释的,这两种会话模式不依赖于工作进程。在我的示例中,我还解释了即使重新启动 IIS,您仍然可以访问您的会话数据。

简而言之

会话模式 推荐
InProc
StateServer
SQLServer

Web 场和负载均衡器

这是生产部署中最常用的术语。当我们使用多个 Web 服务器部署应用程序时,这些术语就会出现。使用这些的主要原因是我们需要将负载分配到多个服务器上。负载均衡器用于在多个服务器上分配负载。

如果我们看一下上面的图,客户端请求 URL,它将命中一个负载均衡器,负载均衡器决定访问哪个服务器。负载均衡器会将流量分配到所有不同的 Web 服务器。

现在这如何影响会话?

在 Web 场和负载均衡器场景中处理会话

在 Web 场中处理会话是最具挑战性的工作之一。

InProc:在 InProc 会话模式下,会话数据存储在工作进程的内存对象中。每个服务器都将有自己的工作进程,并将会话数据保存在其内存中。

如果一台服务器宕机,并且请求转到另一台服务器,用户将无法获取会话数据。因此,不建议在 Web 场中使用 InProc。

StateServer:我已经解释了什么是状态服务器以及如何配置状态服务器等。对于 Web 场场景,您可以轻松理解这有多么重要,因为所有会话数据都将存储在单个位置。

请记住,在 Web 场中,您必须确保所有 Web 服务器都具有相同的 <machinekey>。其他事情与我之前描述的相同。所有 *web.config* 文件都将具有相同的会话状态配置 (stateConnectionString)

SQL Server:这是另一种方法,也是我们在 Web 场中可以使用的最佳方法。我们需要首先配置数据库。所需的步骤已经解释完毕。

explor37.jpg

如上图所示,所有 Web 服务器会话数据都将存储在单个 SQL Server 数据库中。并且易于访问。请记住一件事,您应该在 StateServer 和 SQLServer 模式下都序列化对象。如果其中一台 Web 服务器宕机,负载均衡器会将负载分配到其他服务器,并且用户仍然可以从服务器读取会话数据,因为数据存储在集中式数据库服务器中。

总而言之,我们可以在 Web 场中使用 StateServer 或 SQLServer 会话模式。我们应该避免 InProc。

会话和 Cookie

客户端使用 cookie 与会话协作。因为客户端需要在每个请求中提供相应的会话 ID。我们可以通过以下方式实现这一点

使用 Cookie

当使用会话集合时,ASP.NET 会自动创建一个名为 ASP.NET_SessionId 的特殊 cookie。这是默认设置。会话 ID 通过该 cookie 传输。

Cookie 混淆

一些旧版浏览器不支持 cookie,或者用户可能在浏览器中禁用了 cookie,在这种情况下,ASP.NET 会在经过特殊修改(或“混淆”)的 URL 中传输会话 ID。

Cookie 混淆是如何工作的?

当用户请求服务器上的页面时,服务器会对会话 ID 进行编码,并将其添加到页面中的每个 HREF 链接中。当用户点击链接时,ASP.NET 会解码该会话 ID 并将其传递给用户请求的页面。现在请求页面可以检索会话变量。如果 ASP.NET 检测到用户的浏览器不支持 cookie,所有这些都会自动发生。

如何实现 Cookie 混淆?

为此,我们必须将会话状态设置为无 cookie。

移除会话

以下是用于移除会话的方法列表

方法 描述
Session.Remove(strSessionName); 从会话状态集合中移除一个项。
Session.RemoveAll() 从会话集合中移除所有项。
Session.Clear() 从会话集合中移除所有项。注意:ClearRemoveAll 之间没有区别。RemoveAll() 内部调用 Clear()
Session.Abandon() 取消当前会话。

启用和禁用会话

为了优化性能,我们可以启用或禁用会话,因为每个页面的读写访问都涉及一些性能开销。因此,根据需求启用和禁用会话总是比始终启用会话更好。我们可以通过两种方式启用和禁用会话状态

  • 页面级别
  • 应用程序级别

页面级别

我们可以使用 Page 指令中的 EnableSessionState 属性在页面级别禁用会话状态。

explor38.gif

这将禁用该特定页面的会话活动。

同样,我们也可以将其设置为只读。这将允许访问会话数据,但不允许将会话数据写入会话。

explor39.gif

应用程序级别

可以使用 *Web.Config* 中的 EnableSessionState 属性禁用整个 Web 应用程序的会话状态。

explor40.gif

我们通常使用页面级别,因为某些页面可能不需要任何会话数据或可能只读取会话数据。

参考文献

总结

希望您现在真正熟悉会话、其用途以及如何在 Web 场中应用它等。总结如下

  • 内存内 (InProc) 会话提供程序是最快的,因为所有内容都存储在内存中。如果重新启动 Web 服务器或回收工作进程,会话数据将丢失。您可以在用户数量较少的小型 Web 应用程序中使用此功能。请勿在 Web 场中使用 InProc。
  • StateServer 会话模式下,会话数据由 *aspnet_state.exe* 维护。它将会话数据保留在 Web 服务器之外。因此,Web 服务器的任何问题都不会影响会话数据。您需要先序列化对象,然后才能将数据存储在 StateServer 会话中。我们可以在 Web 场中安全地使用此功能。
  • SQLServer 会话模式将数据存储在 SQL Server 中。我们需要提供连接字符串。在这里,我们还需要在将会话数据存储到会话之前对其进行序列化。这在具有 Web 场的生产环境中非常有用。
  • 我们可以使用 自定义 提供程序来处理自定义数据源,或者当我们需要使用现有表来存储会话数据时。我们还可以在自定义模式下创建自定义会话 ID。但不建议创建自己的自定义提供程序。建议使用第三方提供程序。

希望您喜欢这篇文章。请提供您的建议和反馈以供进一步改进。再次感谢您的阅读。

进一步研究和参考

我已经添加了一些在各个部分。这里我再提供一些链接,这些链接将真正帮助您进一步研究

历史

  • 2009 年 1 月 15 日:首次发布。
  • 2009 年 1 月 24 日:更新:部分内容,修正拼写和语法。
  • 2009 年 1 月 25 日:更新:添加了参考资料和内容以供进一步研究。
© . All rights reserved.