会话状态服务器 vs 自定义会话状态提供程序

3

我被指定为扩展应用程序的会话规模。通过我的研究,最明显的选择是使用状态服务器会话提供程序,因为我不需要用户会话持久化(SQL Server会话提供程序)。

关于应用程序:

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

在深入IT方面之前,鉴于ASP.NET 4提供自定义会话提供程序的能力,我是否应该考虑自定义会话状态提供程序?为什么或为什么不?有没有什么好的自定义会话提供程序?

谢谢!用户反馈:

  • 为什么使用会话:在postbacks之间持久化数据(例如用户选择)
  • 如何:用户进行选择,选择被存储。用户离开页面并返回,选择被恢复等等。
  • 将创建一个Web farm

1
很难回答不知道您使用会话的原因和方式,但也要考虑Server AppFabric(以前称为Velocity)。 - Craig Stuntz
你说的“怎么做”是什么意思?我认为AppFabric是用于缓存的。 - O.O
1
嗯,会话状态在后续请求之间是缓存的。 - n8wrl
1
Session 是一个缓存。它与常规的 Cache 不同,因为它是针对特定用户的。 - Craig Stuntz
4个回答

5
这取决于您所说的“扩展”会话存储的含义。如果您只是谈论会话状态性能,那么您不会打败进程内会话状态提供程序。转换到State Server提供程序实际上会使事情变慢,因为需要在进程边界上序列化和传输对象的额外开销。
State Server可以帮助您扩展的地方在于,它允许负载平衡Web农场中的多台计算机共享单个会话状态。但它受限于机器内存,如果您将有大量并发会话,则可能要使用SQL会话状态提供程序。
对于Web农场中的最佳性能,您还可以尝试使用先前建议过的AppFabric。我自己没有做过,但在这里已经解释了此外,这是一个用Memcached作为会话状态提供程序的链接。同样,我没有使用过,所以无法对其发表意见...

编辑:正如评论中@HOCA所提到的,如果成本不是问题,可以使用第三方解决方案。我听说过一个(但没有使用)叫做ScaleOut SessionServer


State Server也有其局限性,无法将会话状态分布在多个State Server之间。虽然SQL会话状态提供程序可能会在SQL服务器集群中进行潜在的扩展,但其较慢的性能和高昂的成本使其不是理想的选择。 - HOCA
2
+1 - 对于 Web Farm,您必须使用进程外会话状态。根据您现有的基础架构设置,设置 SQL 状态可能是最容易开始的。如果单个 SQL 的负载过高,您可以将会话状态分割到多个服务器之间(使用 partitionResolverType - http://msdn.microsoft.com/en-us/library/h6bb9cz9.aspx)。 - Alexei Levenkov
2
过去,我们已经成功地实现了自己的定制Memcached会话状态提供程序。优点是速度和成本。缺点(三年前)是可靠性。我相信自从我们实施以来,Memcached及其.NET接口已经有了很多更新,因此如果成本是一个问题,这可能是值得考虑的选项。如果成本不是问题,请评估第三方解决方案,因为它们可能提供更好的可靠性和支持。 - HOCA

5

这些看起来很有帮助,所以我将它们放在你的答案里 :) 欢迎来到Stack Overflow! - Craig Stuntz
谢谢,我已经潜水很久了 :) - tenor
很棒的链接。特别是第一个。谢谢。 - O.O

1

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

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

对于单个服务器实例,这是可以接受的,因为您只需从 Web 服务器的本地内存中提取它。这些应用程序的负载往往相当小,所以将特定于用户的信息缓存到本地是有意义的。

但是,一旦您将会话存储转移到另一个服务器,您就增加了应用程序的网络要求和页面加载时间。也就是说,每个页面都会导致会话数据从远程服务器移动到网络线路上,然后进入Web服务器的内存。

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

有些情况下,从数据库服务器按需获取数据所需的时间比从远程会话服务器获取数据需要更长的时间或导致更多的流量。

考虑到很多人将他们的数据库服务器设置为会话服务器,你就开始明白为什么使用会话不合理了。

我只会在获取数据的时间超过“合理”时间时才考虑在负载均衡的 Web 应用程序中使用会话。例如,如果您需要运行一个非常复杂的查询来返回单个值,并且这个查询需要运行很多页面。但即使是这种情况,也有更好的方法来减少处理远程会话数据的复杂性。


会话变量在每个页面加载时都进行序列化和反序列化,无论页面是否使用该数据。这是默认行为,但作为一般性陈述是错误的,如果性能是一个问题,您应该明确设置所需的行为。请参阅http://msdn.microsoft.com/en-us/library/system.web.sessionstate.sessionstatebehavior.aspx。 - Craig Stuntz
@Chris:绝对是值得思考的问题,我已经反复琢磨了很多次。然而,鉴于我的问题中提供的信息,你会如何“评估”在我的情况下是否需要会话?你有什么建议? - O.O
1
@subt13:我会将这些选择存储在数据库的表中。如果它应该持久化,那么这将允许您控制它的持续时间,并在他们注销后仍然保留这些选择。 - NotMe
@Chris - 我必须承认,我从未考虑过那种可能性。 - O.O
我决定尝试这种方法。 - O.O
显示剩余6条评论

-1

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

特别是对于您的“非常小的对象”,请使用视图状态。为什么?

  1. 最好的扩展性。服务器上没有任何需要记住的内容。
  2. 不用担心会话超时。
  3. 不用担心 WebFarm。
  4. 不用担心浪费资源来处理永远不会回来的会话。

特别是在 ASP.NET 4 中,视图状态可以非常可管理和小。


会话是有原因的 :) Viewstate 是页面特定的。增加 Viewstate 会减慢页面速度。Viewstate 不可靠。除此之外,我同意。 - O.O
1
@subt13:我不同意会话是一个“必要的恶”。特别是必要的部分。会话提供的价值超过它的问题的情况非常少。如果这是一个有限生命周期的应用程序,永远不会在多台服务器上运行,那么可以接受。 - NotMe
1
@subt13:你可能想阅读我在这里的答案。 你在session中存储的所有数据都会加载到每个页面,即使那些页面不使用这些值。 这是很多流量,有更好的方法。 - NotMe
1
我给这篇文章点了一个+1,因为它提供了一种新颖且不常见的观点,具有其自身的优点——前提是您有经验并确切知道自己在做什么。我认为如果你只说“尝试/验证/考虑等”而不是用命令式的“不要这样做”,那么你的帖子会更受其他人的欢迎。对于初学者来说,命令形式很危险。但这仍然是一个重要的观点,请重新措辞! - quetzalcoatl
@quetzalcoatl:谢谢您的建议。我会照做的。 - n8wrl
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接