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

理解 ASP.NET 中的会话管理技术

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.77/5 (72投票s)

2012 年 7 月 5 日

CPOL

10分钟阅读

viewsIcon

493338

downloadIcon

5449

在本文中,我们将尝试了解在 ASP.NET 应用程序中管理会话的不同方式。我们应该在何时使用哪种技术,以及使用每种技术的优缺点。

引言

在本文中,我们将尝试了解在 ASP.NET 应用程序中管理会话的不同方式。我们应该在何时使用哪种技术,以及使用每种技术的优缺点。

背景

Web 网站和 Web 应用程序基本的无状态特性对于任何刚开始进行 Web 开发的人来说都相当令人困惑。ASP.NET 提供了多种处理状态的方式。所有状态管理技术的基本概述可以在此处找到。

在本文中,我们将专门讨论会话管理技术。会话是管理应用程序状态的服务器端方法,即,如果使用此技术,所有 Web 应用程序的状态相关信息都将存储在服务器端。这种技术的好处是,由于我们将所有状态相关信息都保存在服务器上,请求和响应变得轻量。此外,他人拦截或更改此数据的可能性也降低了。但这种技术确实涉及更多的服务器资源使用。

使用会话状态的优点是

  • 更好的安全性
  • 减少带宽

使用会话状态的缺点是

  • 服务器资源消耗更多。
  • 如果使用 Web 场,则需要额外的代码/注意(我们稍后会讨论)

让我们开始研究如何在应用程序中使用会话状态,并了解如何配置它以使用各种技术。

认识参与者

使用会话状态

ASP.NET 允许我们使用会话状态保存值。它是一种全局存储机制,可从 Web 应用程序中的所有页面访问。会话状态存储在会话键/值 字典中。此信息将是用户特定的,即,为每个用户创建单独的字典,并且任何人都无法访问其他会话信息。下面是会话的示例用法。

//global.asax
void Session_Start(object sender, EventArgs e)
{
    // Code that runs when a new session is started
    Session["number"] = 0;
}

// Web forms
Session["number"] = Convert.ToInt32(Session["number"]) + 1;

Label6.Text = Session["number"].ToString();s

枚举会话管理技术

在继续之前,让我们看看 ASP.NET 框架中存在哪些会话管理技术。

  • 进程内 (In-Proc)。
  • SQLServer。
  • 状态服务器 (StateServer)。

如何配置会话

要配置会话管理,我们需要在web.config文件中指定设置。web.config中的典型设置如下所示

<sessionState mode="InProc" 
                stateConnectionString="tcpip=127.0.0.1:42424" 
                sqlConnectionString="Data Source=.\SQLEXPRESS;Trusted_Connection=Yes;" 
                cookieless="false" 
                timeout="100"/>

让我们看看这些属性各代表什么。

模式 这指定了我们想要使用的会话管理类型。它可以是InProcSQLServerStateServer
stateConnectionString 如果我们将StateServer用作会话管理技术,那么这将指定处理会话数据的服务器位置。
sqlConnectionString 如果我们将SQLServer用作会话管理技术,那么这将指定存储会话数据的数据库连接字符串
cookieless 这指定了我们是否将使用cookies来识别会话,或者我们是否希望将会话信息附加到 URL 中。它可以是truefalse
timeout 这指定了会话应保持活动的时间。在此段不活动时间后,会话将过期。

单服务器 vs Web 场

网站需要托管服务器。如果我们的网站流量很高,为了提高性能,我们可能会选择使用多个 Web 服务器。如果我们需要多个 Web 服务器(Web 场),我们需要在单个点(即负载均衡器)处理所有请求。负载均衡器将接受所有请求并将其转发到适当的服务器(根据服务器负载和其他一些标准)。

单服务器

与负载均衡器设置

注意:为什么这很重要,很快就会清楚。

配置会话模式

使用进程内会话模式 (In-Proc Session Mode)

如果使用In-Proc会话处理,则所有会话信息将存储在服务器内存中。这是 ASP.NET 中默认的会话状态。

只要我们保存的会话信息量很小,这种方法就工作得很好。由于内存位置由 ASP.NET 工作线程单独处理,因此工作线程管理这些信息会产生相当大的开销。此外,由于这些信息存储在服务器内存中,大容量会话信息可能会导致更多的内存使用,从而降低性能。

让我们尝试可视化这种会话管理技术。

要配置进程内会话管理,我们需要在web.config文件中指定sessionState元素。让我们看看如何配置进程内会话。

<sessionState mode="InProc" 
                stateConnectionString="tcpip=127.0.0.1:42424" 
                sqlConnectionString="Data Source=.\SQLEXPRESS;Trusted_Connection=Yes;" 
                cookieless="false" 
                timeout="100"/>

此配置元素中In-proc会话模式唯一相关的选项是mode(指定我们正在使用In-proc会话)、cookieless(如果为 true,将使用它来管理会话,否则将会话管理数据附加到 URL 中)和timeout(会话应过期的时间)。

当我们希望在会话中存储少量信息时,建议使用In-Proc会话。由于会话数据存储在计算机内存中,可由 ASP.NET 工作线程直接访问,因此无需额外操作。

使用In-Proc模式会话模式的问题是,如果会话数据的大小变大,就会影响性能。此外,由于会话数据存储在服务器内存中,应用程序重启(ASP.NET)将有效地清除所有数据。

Web 场场景中的进程内会话

正如我们上面讨论的,Web 场将有一个负载均衡器接受所有请求。然后,它将根据某些标准将请求转发到任何服务器。让我们尝试看看如果我们使用进程内会话可能导致问题的情况。

问题场景

  1. 来自Computer1的请求到达负载均衡器,负载均衡器将其转发到server1
  2. 进程内会话导致会话数据在server1的内存中创建。
  3. 下一个请求来自 Computer1,这次负载均衡器将其推送到Server2
  4. 由于server1在其内存中保存了此用户特定数据,server2将无法识别此请求,从而导致我们的应用程序逻辑失败。

那么我们应该如何处理这种情况呢?整个问题是因为我们的 web 表单中的每个服务器都将会话数据保存在自己的内存中。如果我们能够以某种方式将会话数据从每个服务器内存移动到集中位置,那么我们就不会遇到这个问题。这就是SQLServerStateServer来拯救的地方。使用这两种方法,我们可以轻松配置一个中央存储库来存储会话数据。

注意:仍然可能存在一些原因(如下所述)会迫使您在 Web 场场景中使用In-Proc会话。如果出现这种情况,则应将负载均衡器配置为保持连接亲和性粘滞会话,以便来自特定客户端的请求始终转发到同一服务器,从而始终可以找到会话信息。

使用 SQLServer 会话模式

如果我们使用SqlServer会话管理模式,那么会话数据将存储在SqlServer中。这种场景的好处是数据存储在集中式数据库中,而不是服务器内存中。让我们看看如何从web.config配置它

<sessionState mode="SQLServer" 
                stateConnectionString="tcpip=127.0.0.1:42424" 
                sqlConnectionString="Data Source=.\SQLEXPRESS;Trusted_Connection=Yes;" 
                cookieless="false" 
                timeout="100"/>

除此之外,还需要配置SQLServer来存储会话数据。为此,只需在Visual Studio 命令提示符中键入aspnet_regsql,然后会打开一个配置向导。在这里,我们可以配置SQLServer以处理会话数据。演示项目已在本地机器上为此配置了sqlexpress。要运行应用程序,您必须在本地机器上配置sqlserver,并且可能需要更改网站的 web.config。

注意:我提供了配置SqlServer的简单分步指南,因为我希望将本文保持在概念层面,而不是成为一个“如何操作”指南。

这样,服务器内存就不会受到会话数据大小的影响。此外,如果存在 Web 场,则使用会话数据不会遇到任何问题,因为会话数据位于中央位置。让我们尝试可视化此场景。

使用此模式只会涉及检索会话数据的额外数据库访问开销。但是,当我们计划使用此技术时,有一个重要的方面需要记住。我们需要向SqlServer数据库发送和接收数据,这将是一个独立的服务器。为了成功地向SqlServer发送和接收数据,会话中保存的所有数据都必须是可序列化的。当应用程序从单个服务器移植到 Web 场时,这有时会成为一个非常大的问题。这就是负载均衡器的连接亲和性将与In-Proc会话一起发挥作用的地方。

使用 StateServer 会话模式

如果我们使用StateServer会话管理模式,那么会话数据将存储在单独的计算机(服务器)中,并且会话数据将由 Windows 服务处理。这种场景的好处是数据存储在集中位置,即状态服务器中,而不是单独的服务器内存中。让我们看看如何从web.config配置它

<sessionState mode="StateServer" 
                stateConnectionString="tcpip=127.0.0.1:42424" 
                sqlConnectionString="Data Source=.\SQLEXPRESS;Trusted_Connection=Yes;" 
                cookieless="false" 
                timeout="100"/>

除此之外,作为状态服务器的服务器也需要配置为存储会话数据。为此,只需运行名为ASP.NET 状态服务的服务,即可使所需的服务器处理会话数据。演示项目在本地机器上进行了相同的配置。要运行应用程序,您必须在本地机器上运行该服务,并且可能需要更改网站的 web.config。

注意:我提供了一个粗略的分步指南来在本地机器上配置状态服务器,因为我希望将本文保持在概念层面,而不是成为一个“操作指南”。

这样,服务器内存就不会受到会话数据大小的影响。此外,如果存在 Web 场,则使用会话数据不会遇到任何问题,因为会话数据位于中央位置。让我们尝试可视化此场景。

使用此模式只会涉及检索会话数据的网络延迟开销。但是,当我们计划使用此技术时,有一个重要的方面需要记住。我们需要向状态服务器发送和接收数据。为了成功地向状态服务器发送和接收数据,会话中保留的所有数据都必须是可序列化的。当应用程序从单个服务器移植到 Web 场时,这有时会成为一个非常大的问题。这就是负载均衡器的连接亲和性将与In-Proc会话一起发挥作用的地方。

使用代码

测试应用程序包含 3 个网站,每个网站只有一个页面。从功能上讲,所有网站都在做同样的事情,但每个网站都使用不同的会话管理技术。

要运行所有三个网站,必须配置本地机器上的Sqlserver以存储会话特定数据(详细信息见上方相应类别),并且 ASP.NET 状态服务应在本地机器上运行。此外,连接字符串也必须相应修改,以使用正在运行的计算机上的数据库。

注意:请参考每个网站的web.config以了解细微差别。

应用程序运行时将如下所示

关注点

前段时间我有一个任务,将一个在单服务器上运行的网站迁移到 Web 场。由于我不知道本文中提供的所有信息,对我来说简直是一场噩梦。我实际上将in-proc模式更改为StateServer模式,然后应用程序开始抱怨推送到会话中的数据不可序列化

然后我深吸一口气,阅读了所有关于会话的资料。我现在对如何配置会话有了一些理解。我试图通过这篇文章传达相同的信息。至于我遇到的任务,我最终使用了in-proc会话,并在负载均衡器上配置了粘滞会话。这只是一个临时措施,直到我有机会使此应用程序中的所有内容都可序列化

历史

  • 2012 年 7 月 5 日:第一版。
理解 ASP.NET 中的会话管理技术 - CodeProject - 代码之家
© . All rights reserved.