我刚刚发现,ASP.Net Web应用程序中的每个请求在请求开始时都会获得一个Session锁,然后在请求结束时释放它!
如果这对你造成影响,就像我一开始对你而言,这基本上意味着以下几点:
任何时候ASP.Net网页需要很长时间才能加载(可能是由于数据库调用速度慢等),并且用户决定他们想要导航到另一个页面,因为他们厌倦了等待,他们不能!ASP.Net会话锁强制新页面请求等待,直到原始请求完成其缓慢的负载.Arrrgh.
任何时候UpdatePanel加载缓慢,并且用户决定在UpdatePanel完成更新之前导航到另一个页面......他们不能!ASP.net会话锁强制新页面请求等待原始请求完成其缓慢的负载.双Arrrgh!
那有什么选择呢?到目前为止,我想出了:
我真的不敢相信ASP.Net微软团队会在版本4.0的框架中留下如此巨大的性能瓶颈!我错过了一些明显的东西吗 为会话使用ThreadSafe集合有多难?
ASP.Net会话看起来非常适合传统的WebForms应用程序,但它们会为现代AJAX和MVC应用程序做一些严重问题.
具体来说,只有3种方法可以访问ASP.Net提供者:
锁定读写(默认) - 会话被锁定,AcquireRequestState直到ReleaseRequestState触发为止.如果浏览器立即发出3个请求,他们将在服务器上排队.这是MVC 2中唯一的选择,但MVC 3允许......
非锁定只读 - 会话未锁定,但无法保存.这似乎是不可靠的,因为有些读取似乎再次锁定会话.
会话已禁用 - 任何读取或写入会话的尝试都会引发异常.
然而,对于一个现代的MVC应用程序,我有很多AJAX事件同时发生 - 我不希望它们在服务器上的队列,但我希望他们能够写入会话.
我想要的是第四种模式:脏读,最后写赢
我认为(很高兴得到纠正)唯一的办法就是完全取代ASP.Net的会话.我可以编写自己的提供程序,但ASP仍会使用它支持的3个模式中的一个调用它.有没有办法让ASP.Net支持乐观并发?
这使得我用一个基本上做同样事情的新类替换对会话的所有调用,但是没有锁定 - 这是一个痛苦.
我希望保留尽可能多的当前会话内容(最重要的是在各种日志中的会话ID),并且代码更换量最少.有没有办法做到这一点?理想情况下,我想HttpContext.Current.Session指向我的新类,但没有ASP.Net锁定任何请求.
有没有人做过这样的事情?看来奇怪的是,所有的AJAXey MVC应用程序都是ASP的一个新问题.
在我们的一个生产服务器上,偶尔会在会话模块中将请求卡在RequestAquireState中.因为它是一个MVC请求,它不会超时,所以我们有时会得到在后台运行几个小时的请求.
我们在.net4和IIS 7.5上使用标准的asp.net会话模块我们正在使用InProc.
为什么会卡住?
在繁重的负载下或使用jQuery的ajax中止功能时,我们看到IIS中建立了请求,以至无人可以连接并且整个站点都挂起,从而迫使回收。
一个从3年前类似的帖子也有类似的问题与.NET 4.5和IIS 7.5,但微软已表示这是固定在4.5.1和发布了一个补丁4.5。
在尝试使用State Server的Windows Server 2012R2上,使用IIS 8时会出现此问题,在运行Windows 10和IIS10的开发计算机上使用State Server时,甚至更是如此。补丁程序无法安装在任何这些机器上,因为安装程序被4.5.1阻止。更改为In Proc可以减少问题的发生,但不能完全解决问题。
今年IIS论坛上的这个死线程有其他几个问题相同,但没有解决方案。我还尝试将别处建议的UploadReadAheadSize设置为0,但这并不能解决问题。
是否还有其他人对此有经验和/或找到解决方案?任何投入将不胜感激。
asp.net ×4
iis ×3
session ×3
architecture ×1
concurrency ×1
hang ×1
iis-7 ×1
iis-8 ×1
performance ×1