问题 对ASP.NET站点的更改是否会终止活动会话?


我担心我的用户会话被扫除的可能性。我使用默认的ASP.NET Session对象和会话cookie。我知道会话可以超时,我已将会话的超时值设置为几个小时,以避免意外超时。

但至少有两个我担心的案例。

(1)据我所知,ASP.NET会定期回收运行网站/网络应用程序的应用程序域(不确定我的所有术语是否正确)。这些回收活动会有会议吗?

(2)至少在我的开发服务器上,我对网站所做的某些更改(例如,添加新页面)似乎会导致活动会话在重新编译网站(或部分网站)时丢失。这种情况似乎不会随着每一次变化而发生,但有很多变化。我特别关注这对于我的网站上线时可能发生的变化意味着什么。我想知道我可以更新的规则,而不会导致活动会话被杀死。

谢谢你的任何指示。


7231
2017-12-28 07:59


起源



答案:


这取决于您的会话状态模式。这是你可以找到的东西的副本 Microsoft支持

ASP.NET支持三种模式   会话状态:

  • 是InProc:In-Proc模式将值存储在ASP.NET的内存中   工人的过程。因此,这种模式提供   最快速地访问这些值。   但是,当ASP.NET工作者   过程循环,状态数据是   丢失。
  • 的StateServer:或者,StateServer模式使用独立模式   要存储的Microsoft Windows服务   会话变量。因为这   服务独立于Microsoft   它是Internet Information Server(IIS)   可以在单独的服务器上运行。您可以   使用此模式进行负载平衡   解决方案因为多个Web服务器   可以共享会话变量。虽然   会话变量如果你没有丢失   重启IIS,性能受到影响   当你跨越过程边界。
  • SqlServer的:如果你非常关心持久性   会话信息,您可以使用   SqlServer模式利用Microsoft   SQL Server确保最高级别   可靠性。 SqlServer模式是   类似于进程外模式,除了   会话数据保持在   一个SQL Server。 SqlServer模式也   使您可以使用状态存储   它位于IIS进程之外   那可以位于当地   计算机或远程服务器。

如果使用StateServer或数据库,则当IIS检测到对网站的更改时,会话数据不会丢失。


12
2017-12-28 08:07



@Jochen,添加像'Hi'这样的聊天聊天,'希望它有帮助'等等无关紧要:-) - Jan Jongboom
谢谢。是的,我也发现了这个: hanselman.com/blog/...  我似乎天真地认为InProc解决方案是合理的,但似乎基本没用,因为你永远不知道会话何时会死。我想我会尝试SqlServer选项。 - M Katz
在我看来,如果InProc不是一个选项,StateServer是最容易使用和最佳表现的。 - Jochen
StateServer的问题是会话数据仍然只存在于RAM中,因此如果该进程崩溃或机器重新启动,您仍将丢失所有当前会话。 SQL Server更好,IMO。 - RickNZ


答案:


这取决于您的会话状态模式。这是你可以找到的东西的副本 Microsoft支持

ASP.NET支持三种模式   会话状态:

  • 是InProc:In-Proc模式将值存储在ASP.NET的内存中   工人的过程。因此,这种模式提供   最快速地访问这些值。   但是,当ASP.NET工作者   过程循环,状态数据是   丢失。
  • 的StateServer:或者,StateServer模式使用独立模式   要存储的Microsoft Windows服务   会话变量。因为这   服务独立于Microsoft   它是Internet Information Server(IIS)   可以在单独的服务器上运行。您可以   使用此模式进行负载平衡   解决方案因为多个Web服务器   可以共享会话变量。虽然   会话变量如果你没有丢失   重启IIS,性能受到影响   当你跨越过程边界。
  • SqlServer的:如果你非常关心持久性   会话信息,您可以使用   SqlServer模式利用Microsoft   SQL Server确保最高级别   可靠性。 SqlServer模式是   类似于进程外模式,除了   会话数据保持在   一个SQL Server。 SqlServer模式也   使您可以使用状态存储   它位于IIS进程之外   那可以位于当地   计算机或远程服务器。

如果使用StateServer或数据库,则当IIS检测到对网站的更改时,会话数据不会丢失。


12
2017-12-28 08:07



@Jochen,添加像'Hi'这样的聊天聊天,'希望它有帮助'等等无关紧要:-) - Jan Jongboom
谢谢。是的,我也发现了这个: hanselman.com/blog/...  我似乎天真地认为InProc解决方案是合理的,但似乎基本没用,因为你永远不知道会话何时会死。我想我会尝试SqlServer选项。 - M Katz
在我看来,如果InProc不是一个选项,StateServer是最容易使用和最佳表现的。 - Jochen
StateServer的问题是会话数据仍然只存在于RAM中,因此如果该进程崩溃或机器重新启动,您仍将丢失所有当前会话。 SQL Server更好,IMO。 - RickNZ


(1)如果在回收应用程序池时使用进程内会话模式,则会丢失会话信息

(2)取决于您的asp.net应用程序使用Web应用程序或网站模型。某些文件在应用程序启动时缓存,如果更改则需要重新启动或重新编译。经验法则是,如果更改Global.asax,添加,删除或编辑\ bin文件夹中的文件的配置文件,将发出应用程序的重新启动,并且In Process Session数据将丢失。

ASP.NET Session有许多缺陷,许多开发人员根本不使用它。我个人更喜欢将数据存储在SQL Server中的自定义表中(如果可用)。

如果您想提供更多信息,例如您拥有的IIS版本,是使用网站或Web应用程序模型,是否有数据库服务器可用,是使用Web场或Web园服务器环境,以及您希望使用哪些信息存储以及我可以给你多长时间的具体建议。


3
2017-12-28 08:47



感谢您提供更多信息。你是说你甚至不使用sql server版本的ASP.NET会话? ASP.NET sql会话有哪些缺陷? - M Katz
在默认模式下,会话模块导致两次到DB的往返:一次在页面开头读取数据并更新会话到期时间,另一次在页面末尾更新会话数据。此外,它会对会话数据发出独占锁定,因此如果您必须来自可以并行运行的同一用户的页面(例如使用框架或Ajax),由于锁定,它们将被强制连续运行。您可以通过标记不需要会话状态的页面或仅以只读模式需要的页面来缓解某些问题。 - RickNZ
我完全同意RickNZ。开箱即用的会话编程模型也不是很好,因为需要进行强制转换,并且会话中没有对象的管理。我们有一种说法:ASP.NET会话就像一只猪 - 它让你吃得很好。如果你想使用会话我建议创建一个代理类,它将所有要放入其中的对象公开为属性。 - Branislav Abadjimarinov
代理类或代理服务器?听起来在共享托管环境中可能不那么容易,对吧? - M Katz
我的评论是关于编程模型而不是托管环境。使用会话时,可以使用索引器访问其中的对象,并且需要转换结果。如果要访问类型化数据,则必须创建一个访问会话并返回数据的类。通常使用代理设计模式来实现该类。这样您就可以控制会话中对象的类型和类型。 - Branislav Abadjimarinov


如果您正在使用InProc模式,那么如果AppPool回收,您将丢失会话数据,这可能每天发生一次(根据默认计划),或者在服务器上大约20分钟不活动后发生。

关于页面更新:每次更改实时站点上的文件时,站点都有可能重新启动,就像您更改了web.config一样。某些文件不会导致完全重启,但预测哪些文件并不容易,而且还取决于您正在使用的编译模式(批处理或不批处理)。如果您使用的是默认的每文件夹批处理编译模式,则应该能够更改子文件夹中的各个页面而不强制重新启动。但是,对主页面,代码或控件的更改可能会导致重新启动,因为可以更改顶级文件夹(具体取决于您拥有的其他内容)。

我想我应该补充说,改变现场网站上的个别文件通常不是一个好主意 - 虽然我确信你有理由这样做。


0
2017-12-28 13:32



感谢您提供更多信息。我可以看出为什么某些变化导致会话丢失而其他人没有导致会产生神秘感。关于升级的问题,如果我想在不关闭站点或中断用户会话的情况下进行小的更改,那么即时进行小的更改会有什么风险(只要我知道它们不会更改会话状态变量等等) 。)? - M Katz
请记住,在默认模式下,当您更改一个文件时,将重新编译该文件夹中的所有文件。在此期间,尝试访问任何这些文件的用户将被迫等待。如果文件夹足够大或者有足够多的用户尝试访问这些文件,那么您的工作线程都可以被占用,并且整个站点可以暂停,直到重新编译完成。在最糟糕的情况下,在繁忙的站点上,队列可能会变满,以至于“服务器太忙”错误导致用户被拒之门外。 - RickNZ