【问题标题】:Pros and Cons of using ASP.NET Session State Server (instead of InProc)?使用 ASP.NET 会话状态服务器(而不是 InProc)的优缺点?
【发布时间】:2011-02-12 10:41:17
【问题描述】:

在我开始使用会话状态服务器以使我的应用程序中的会话状态与 InProc 状态相比更加健壮之前,我想找到一个优缺点列表进行评估。

更新 1:还有关于幸存的应用程序池回收吗?

更新 2:会话的持续时间及其结束情况如何?

【问题讨论】:

  • 或许应该将其标记为社区 wiki。
  • @Tom:每个人都要求社区 wiki 的情况如何?这不是“你最喜欢的卡通片是什么?”,而是一个有效的问题。
  • 人们经常在一个有一个对多个正确答案的问题(不需要 wiki)和一个主观的问题(用于 wiki)之间混淆。我的问题是前一种。
  • 我更新了我的答案以尝试解决您的更新 1,但并不真正理解您对会话的寿命及其结束的问题。

标签: asp.net session stateserver session-state


【解决方案1】:

ASP.NET 中会话的缺点

  • 每个变量都存储为对象。这意味着您需要在读取会话变量时将 Object 转换为特定类型。

  • 除此之外,如果会话为空,则 Object 将为空。在读取会话变量之前,您需要检查它是否为空。即使变量之前已初始化,它也可能为 null,因为会话已过期。尝试使用空会话值可能会返回异常。如果会话变量的值为 null,通常的做法是使用一些默认值而不是无意义的 null。如果 value 不为 null,则必须将其转换为适当的类型,因为所有会话变量都是对象类型。在做所有这些事情的时候,你应该注意避免硬编码。有关以可扩展和可维护的方式读取和写入会话变量的更多信息,您可以在如何写入、读取和删除会话状态变量教程中阅读。

  • 变量名是字符串类型。如果您硬编码变量的名称,则可以选择在某处犯类型错误。问题是,如果您尝试读取不存在的会话变量,ASP.NET 将不会返回任何异常或警告。它只会创建具有空值的错误名称的新变量。这些类型的错误可能很难找到。

  • 不应将会话数据用于存储敏感数据。恶意用户有可能获取常规访问者的会话 ID。如果会话状态用于存储诸如“是否允许访问管理区域”之类的信息,攻击者可以看到网站的敏感数据、其他人的私人数据、编辑数据库、删除内容等。

  • 如果使用 InProc 模式,会话很容易耗尽所有服务器资源,从而降低网站性能。

状态服务器

SQL Server 是所有模式中最可靠的。如果 ASP.NET 重新启动,但如果 SQL Server 重新启动,会话数据将保持不变。

SQL Server 也是最具可扩展性的选项。

SQL Server 常用于共享主机场景

自定义模式

您可以完全控制会话。甚至可以创建自定义会话 ID。

您可以支持不同的数据源。这对于将会话数据存储在其他数据库(如 Oracle、MySQL、MS Access 等)上可能很有用。

有关其他详细信息,您可以click here to view ASP.NET Session state advantages。希望我的回答对你有帮助。! :)

【讨论】:

    【解决方案2】:

    State Server 是一个伟大的(!) 入门选择。为什么?因为这意味着您的应用程序现在与任何进程外存储模式兼容。

    如果您目前使用InProc 开发您的网站,并希望稍后移至StateServerSqlServer,您可能会遇到序列化问题。并非总是如此,但确实会发生。

    一些例子包括(一些已经提到):

    • Ops 开始在您不知情的情况下安排定期 IIS 应用程序池回收
    • 内存经常不足
    • 您将在生产环境中使用负载均衡器,不能保证同一个网站会收到相同的请求。

    因此,最好尽早解决这个问题。它只是一个配置更改和一个服务启动;轰隆隆!

    这也意味着,如果您决定采用完全不同的会话存储路线,例如使用 Redis(分布式键/值存储)或 RavenDB(文档数据库),那么您已经排序。

    这真的是对 1 分钟工作的良好投资。您现在已准备好使用网络场、负载平衡器和您决定对其进行原型设计的任何其他会话管理系统。

    【讨论】:

    • 如果我们使用 Redis 作为 sessionState Provider,我们是否需要在存储到 session 之前序列化所有对象?
    • @Saineshwar:我相信是的。如果没有序列化,.NET 不知道读取/写入的格式(默认情况下)。
    【解决方案3】:

    以下是 Rob Howard 的 ASP.NET Session State 文章中对您的三个选项的优缺点的规范分析:

    • 处理中。由于会话状态内存保存在 ASP.NET 进程中,因此进程中的性能最佳。对于托管在单个服务器上的 Web 应用程序,保证用户被重定向到正确服务器的应用程序,或者当会话状态数据不重要时(从某种意义上说,它可以重新构造或重新填充) ,这是可以选择的模式。

    • 进程外。当性能很重要但您不能保证用户将从哪个服务器请求应用程序时,最好使用此模式。使用进程外模式,您可以获得从内存读取的性能以及管理所有服务器状态的单独进程的可靠性。

    • SQL 服务器。当数据的可靠性是应用程序稳定性的基础时,最好使用此模式,因为数据库可以集群以应对故障情况。性能不如进程外快,但代价是更高级别的可靠性。

    进程外(又名“StateServer”)和 SQL-Server 选项都能在 Web 应用程序重新启动(包括应用程序池循环)后继续存在,并且都使会话数据可用于集群/场中的多个服务器。

    最后,它可能不言而喻,但基本的进程内设置是最容易配置的,这在许多环境中是一个有意义的“专业”。

    Tim Sneath 的 ASP.NET Session State: Architectural and Performance Considerations 添加了一些额外的信息,MSDN topic on Session State Modes 是一个可靠的最新来源。

    【讨论】:

      【解决方案4】:

      我想说使用 In_Proc 的一大缺点是,如果应用程序池或域被回收,会话状态可能会丢失。这可能随时发生,例如,如果服务器内存不足等。我个人从不依赖 In_Proc 会话来处理您不想丢失的任何内容。我花了几个小时调试有零星问题的站点,却发现这是因为服务器资源回收率低导致会话状态丢失(当然,您在会话中存储的越多,服务器资源越少用完。记住,如果它可能出错,那么它可能会在某个时候出错!

      这就是为什么我现在通常将状态服务器用于除了琐碎的会话数据之外的任何事情。我发现唯一真正的缺点是您需要将类标记为可序列化,但这通常是微不足道的。它也有点慢,但在大多数情况下可以忽略不计。

      IIS MSDN 博客上有a good article about this

      【讨论】:

        【解决方案5】:

        另外一个缺点是,如果您在一个场中执行 1 个远程状态服务器,您可能会遇到单点故障。即使不是农场,它仍然值得在本地运行以生存 app_pool IMO。我们赶上了可序列化部分,所以请注意。

        另外,请留意 Windows Server AppFabric 的发布,因为它将替换复制/分布式状态服务器。应该是 1H2010 的 RTM。

        【讨论】:

          【解决方案6】:

          优点:
          1. 可以跨机器访问相同的会话状态。
          2. 重新加载app_pool后会话状态相同。

          缺点:
          1. 比进程模式慢。
          2. 所有处于会话状态的对象都必须是可序列化的。

          【讨论】:

          • 有多慢?由于网络延迟或其他原因而变慢?
          • 几乎是的。在进程中,它使用 IIS 使用的内存。它不必序列化,将数据推送到另一个应用程序等。这也是相对的。只要你的状态服务器和你的应用服务器没有处于不同的状态,减速就不会真的很明显。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-12-02
          • 2012-07-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-24
          相关资源
          最近更新 更多