【问题标题】:Session State Server vs Custom Session State Provider会话状态服务器与自定义会话状态提供程序
【发布时间】:2011-06-09 06:59:07
【问题描述】:

我的任务是扩展应用程序的会话。根据我的研究,最明显的选择是使用 State Server 会话提供程序,因为我不需要用户会话保持(SQL Server 会话提供程序)

关于应用程序:

  • 当前使用 InProc 会话提供程序
  • 存储在会话中的所有对象都是可序列化的
  • 所有对象都很小(主要是简单对象(int、string)和一些简单的类实例)

在我一头扎进 IT 方面并能够使用 ASP.NET 4 提供自定义会话提供程序之前,我是否应该考虑使用自定义会话状态提供程序。为什么或者为什么不?有没有“好”的?

谢谢! 用户反馈:

  • 我们为什么使用会话:回发之间的数据持久性(例如用户选择)
  • 如何:用户做出选择,选择被存储。用户离开页面并返回, 选择被恢复。等等等等。
  • 将创建一个网络农场

【问题讨论】:

  • 在不知道为什么如何使用会话的情况下很难回答,但还要考虑 Server AppFabric(以前称为 Velocity)。
  • “如何”是什么意思?我认为 AppFabric 是用于缓存的。
  • 嗯,会话状态是回发之间的“缓存”。
  • Session 缓存。它与普通的 Cache 不同,因为它是特定于用户的。
  • @Craig - 感谢您的解释。

标签: c# asp.net session architecture asp.net-4.0


【解决方案1】:

我建议不要使用会话状态,无论提供者如何。

尤其是“非常小的对象”使用视图状态。为什么?

  1. 规模最大。服务器上没有什么要记住的。
  2. 不用担心会话超时。
  3. 不用担心网络农场。
  4. 不用担心会浪费资源用于永远不会回来的会话。

尤其是在 ASP.NET 4 中,视图状态可以非常易于管理且很小。

【讨论】:

  • 会话的创建是有原因的:) Viewstate 是特定于页面的。增加视图状态会减慢页面速度。 Viewstate 不可靠。除此之外,我同意。
  • “viewstate 不可靠”是什么意思? viewstate 和 session 都是为了“伪造”网页中的状态而创建的。我之所以发帖只是因为我对会话状态感到心痛,并且您可以采取任何措施来避免它。
  • @subt13:我不同意会话是“'必要'的邪恶”,尤其是必要的部分。在极少数情况下,会话提供的价值超出了它的问题。如果这是一个生命周期有限的应用程序,它永远不会在超过 1 个服务器上运行,那么很好。
  • @subt13:您可能想在这里阅读我的回答。您在会话中存储的所有数据都会为每个页面加载,即使是那些不使用这些值的页面。流量很大,还有更好的方法。
  • 我给这篇文章 +1,因为它提供了一个新的和不常见的观点,它有自己的优点 - 只要你有经验并且确切地知道你在做什么。我认为,如果您只说“try/verify/thinkof/etc”而不是命令式“不要这样做”,其他人会更容易接受您的帖子。在命令式形式中,这对新的 Web 开发人员来说是危险的。还是很重要的观点,请改写!
【解决方案2】:

这取决于您所说的“扩展”会话存储的含义。如果您只是谈论会话状态性能,那么您不会击败进程内会话状态提供者。切换到 State Server 提供程序实际上会使事情变得更慢——因为序列化和跨进程边界传输对象的额外开销。

状态服务器可以帮助您进行扩展的地方在于,它允许负载平衡网络场中的多台计算机共享单个会话状态。但是,它受到机器内存的限制,如果您有很多并发会话,您可能需要使用 SQL 会话状态提供程序。

为了在网络场中获得最佳性能,您还可以尝试使用之前建议的 AppFabric。我自己没有做过,但它是explained here.

Also, here's a link for using Memcached as a Session State provider。再说一次,我没用过,所以不能发表意见……

编辑:正如@HOCA 在 cmets 中提到的,如果成本不是问题,则可以使用第 3 方解决方案。我听说过(但没用过)的是ScaleOut SessionServer

【讨论】:

  • 状态服务器也有不能跨多个状态服务器分布会话状态的限制。虽然 SQL 会话状态提供程序可能会在 SQL Server 集群中进行扩展,但其缓慢的性能和高成本使其不是理想的选择。
  • +1 - 对于网络农场,您必须使用进程外会话状态。根据您现有的基础架构,设置 SQL 状态可能是最容易开始的。如果单个 SQL 的负载太高,您可以在多个服务器之间拆分会话状态(使用 partitionResolverType - msdn.microsoft.com/en-us/library/h6bb9cz9.aspx)。
  • 过去我们已经实现了我们自己的自定义 Memcached 会话状态提供程序并取得了一些成功。专业人士是速度和成本。缺点(3 年前)是可靠性。我敢肯定,自从我们实现 Memcached 及其 .NET 接口以来,它已经进行了大量更新,所以如果成本是一个问题,这可能是一个值得考虑的选项。如果成本不是问题,请评估第 3 方解决方案,因为它们可能会提供更好的可靠性和支持。
【解决方案3】:

【讨论】:

  • 这些似乎很有帮助,所以我将它们放入您的答案中。 :) 欢迎来到 Stack Overflow!
  • 谢谢,我已经潜伏很久了:)
  • 很棒的链接。尤其是第一个。谢谢。
【解决方案4】:

我强烈建议您在考虑扩展会话之前首先评估是否需要会话。

无论页面是否使用该数据,每次页面加载都会对会话变量进行序列化和反序列化。 (编辑:Craig 指出您在 .net 4 http://msdn.microsoft.com/en-us/library/system.web.sessionstate.sessionstatebehavior.aspx 中对此有一定程度的控制,但是,这仍然有缺点,请参阅 cmets 的这个答案。)

对于单服务器实例,这没关系,因为您只是从 Web 服务器的本地内存中提取它。这些应用程序的负载往往非常小,因此在本地缓存用户特定信息是有意义的。

但是,一旦您将会话存储移动到另一台服务器,就会增加应用程序的网络要求和页面加载时间。即,每个页面都将导致会话数据从远程服务器通过网络线移动到 Web 服务器的内存中。

此时您必须问自己:根据需要直接从数据库服务器中提取此信息的负载是否比每次从会话服务器中提取更多?

在少数情况下,根据需要从数据库服务器中提取它比从远程会话服务器中提取它需要更长的时间或导致更多的流量。

请记住,很多人将他们的数据库服务器设置为会话服务器,您开始明白为什么使用会话没有任何意义。

我唯一会考虑将会话用于负载平衡的 Web 应用程序的情况是获取数据的时间超过了“合理”的时间。例如,如果您有一个非常复杂的查询来返回单个值,并且该查询必须针对大量页面运行。但即便如此,仍有更好的方法可以降低处理远程会话数据的复杂性。

【讨论】:

  • “无论页面是否使用该数据,会话变量都会针对每个页面加载进行序列化和反序列化。”这是默认值,是的,但作为一般陈述是错误的,如果性能是一个问题,您应该明确设置您想要的行为。见msdn.microsoft.com/en-us/library/…
  • @Chris:默认。深思熟虑和我无数次思考的东西。但是,鉴于我的问题中的信息,在我的情况下,您将如何“评估”会话的需要?你有什么建议?
  • @Craig:这有两个问题。首先,它是一个覆盖继承类的属性。因此,您必须逐个控制器在页面/页面或控制器上进行设置。其次,如果你有它,那么页面仍然会获取所有会话数据,无论它是否使用了那些特定的项目
  • @subt13:我会将这些选择存储在数据库的表中。如果它应该持续存在,那么这将允许您控制它真正持续的时间,并允许您保留这些选择,即使它们已注销。
  • 我并不认为做正确的事很难。记住这个笑话:“软件中有两个难题:缓存失效和命名事物。”但“不缓存”并不总是一个可以接受的答案。
猜你喜欢
  • 2013-07-21
  • 2012-08-23
  • 2016-06-17
  • 1970-01-01
  • 2015-03-10
  • 2016-06-29
  • 1970-01-01
  • 1970-01-01
  • 2013-10-24
相关资源
最近更新 更多