为什么在添加更多异步请求时请求延迟会增加,从而导致荒谬的加载时间?
Why request latency increases when adding more async requests, resulting in ridiculous load time?
我的 MVC 应用基本上是 1 个主视图和多个局部视图。
我在异步加载部分视图的最小页面上有这个小脚本:
<script>
$(function () {
$('#bookmarks').load('Home/Bookmarks');
$('#calendar').load('Home/Calendar');
$('#gmail').load('Home/Gmail');
$('#weather').load('Home/Weather');
$("#news").load("Home/News");
}
</script>
当我对它们全部进行评论时,我得到了这个(加载速度非常快):
现在我只取消注释 "Bookmarks" 请求(只从本地驱动器读取小 JSON 文件),我得到这个(书签需要 9 毫秒):
现在我取消注释 "Calendar" 请求(Google 日历 API),我明白了(如果请求是异步的,为什么书签延迟从 9 毫秒跳到 1.04 秒?):
现在我取消注释 "Gmail" 请求 (Google Gmail API),我明白了(书签延迟再次从 1.04 秒跳到 1.53 秒?):
现在我取消注释其余的("Gmail"、"Weather" 和 "News" 请求),我得到了这些疯狂增加的延迟,书签请求现在需要 5 秒来执行,而不是9 毫秒 - 为什么?):
您可以看到每个操作的延迟增加 - 看起来这些 ajax 请求根本不是异步的 :( 这怎么可能,当 AJAX 应该是异步的默认值?
我确定我在这里遗漏了一些东西,可能 jQuery 加载函数不是异步的,但它在 javascript 大小上,并且延迟在 server-side 上。我现在很困惑。
更新:显然jQuery调用是异步的,所有加载函数都是同时执行的。这很容易。问题出在服务器端。在进行了一些测试之后,很明显 IIS 同步执行这些请求,顺序 按照它从浏览器接收到它们的顺序一个接一个地执行。我在 IIS 上做了一些额外的阅读,默认情况下 IIS apppool 只有 1 个正在使用的工作进程,可以触发多个线程来处理所有这些请求。 但由于某些原因,请求正在按顺序处理,而不是并行处理。我还没有找到为什么(如果一个 AppPool 工作进程可以启动多个线程进行同时处理)请求仍然按顺序执行,以及如何使这些请求并行处理,如果可能的话。如果有人知道如何使事情正常工作,我真的很想听听。谢谢。
Update 仔细阅读后发现,如果启用了Session,请求是按顺序处理的。会话对象是一个单线程对象。会话对象不能同时被两个线程共享。因此,当同一会话有两个请求时,一个请求排队,而另一个请求正在使用会话对象。这很糟糕 :( IIS 专家有什么建议吗?:)
已解决
是的,会话状态就是问题所在!我在 web.config 中禁用了会话状态并删除了使用 Session 对象以避免运行时错误的一行。现在一切正常。真正的问题确实是 - 会话状态绑定到单个线程,因此在服务器端我的应用程序表现得像一个旧的 STA 放屁:)
http://msdn.microsoft.com/en-us/library/ms178581.aspx
并发请求和会话状态
对ASP.NET会话状态的访问是每个会话独占的,这意味着如果两个不同的用户发出并发请求,则同时授予对每个单独会话的访问权限。但是,如果对同一个会话发出两个并发请求(通过使用相同的 SessionID 值),第一个请求将独占访问会话信息。第二个请求只有在第一个请求完成后才执行。(如果信息的排他锁被释放,第二个会话也可以访问,因为第一个请求超过了锁time-out。)如果@Page 指令中的 EnableSessionState 值设置为 ReadOnly,对 read-only 会话信息的请求不会导致对会话数据的独占锁定。但是,read-only 会话数据请求可能仍需要等待 read-write 会话数据请求设置的锁定来清除。
After some more reading, found that requests are processed
sequentially if Session is enabled. The session object is a single
threaded object. The session object cannot be shared by two threads
simultaneously. Hence when there are two requests for the same session
one is queued while the session object is in use by the other. This
sucks :( Any suggestions, IIS experts? :)
不要使用 Session
。我很少找到证明使用 Session
合理的案例,而且通常很容易找到没有您 运行 所遇到的可扩展性限制的存储替代方案。
我的 MVC 应用基本上是 1 个主视图和多个局部视图。 我在异步加载部分视图的最小页面上有这个小脚本:
<script>
$(function () {
$('#bookmarks').load('Home/Bookmarks');
$('#calendar').load('Home/Calendar');
$('#gmail').load('Home/Gmail');
$('#weather').load('Home/Weather');
$("#news").load("Home/News");
}
</script>
当我对它们全部进行评论时,我得到了这个(加载速度非常快):
现在我只取消注释 "Bookmarks" 请求(只从本地驱动器读取小 JSON 文件),我得到这个(书签需要 9 毫秒):
现在我取消注释 "Calendar" 请求(Google 日历 API),我明白了(如果请求是异步的,为什么书签延迟从 9 毫秒跳到 1.04 秒?):
现在我取消注释 "Gmail" 请求 (Google Gmail API),我明白了(书签延迟再次从 1.04 秒跳到 1.53 秒?):
现在我取消注释其余的("Gmail"、"Weather" 和 "News" 请求),我得到了这些疯狂增加的延迟,书签请求现在需要 5 秒来执行,而不是9 毫秒 - 为什么?):
您可以看到每个操作的延迟增加 - 看起来这些 ajax 请求根本不是异步的 :( 这怎么可能,当 AJAX 应该是异步的默认值?
我确定我在这里遗漏了一些东西,可能 jQuery 加载函数不是异步的,但它在 javascript 大小上,并且延迟在 server-side 上。我现在很困惑。
更新:显然jQuery调用是异步的,所有加载函数都是同时执行的。这很容易。问题出在服务器端。在进行了一些测试之后,很明显 IIS 同步执行这些请求,顺序 按照它从浏览器接收到它们的顺序一个接一个地执行。我在 IIS 上做了一些额外的阅读,默认情况下 IIS apppool 只有 1 个正在使用的工作进程,可以触发多个线程来处理所有这些请求。 但由于某些原因,请求正在按顺序处理,而不是并行处理。我还没有找到为什么(如果一个 AppPool 工作进程可以启动多个线程进行同时处理)请求仍然按顺序执行,以及如何使这些请求并行处理,如果可能的话。如果有人知道如何使事情正常工作,我真的很想听听。谢谢。
Update 仔细阅读后发现,如果启用了Session,请求是按顺序处理的。会话对象是一个单线程对象。会话对象不能同时被两个线程共享。因此,当同一会话有两个请求时,一个请求排队,而另一个请求正在使用会话对象。这很糟糕 :( IIS 专家有什么建议吗?:)
已解决 是的,会话状态就是问题所在!我在 web.config 中禁用了会话状态并删除了使用 Session 对象以避免运行时错误的一行。现在一切正常。真正的问题确实是 - 会话状态绑定到单个线程,因此在服务器端我的应用程序表现得像一个旧的 STA 放屁:)
http://msdn.microsoft.com/en-us/library/ms178581.aspx
并发请求和会话状态
对ASP.NET会话状态的访问是每个会话独占的,这意味着如果两个不同的用户发出并发请求,则同时授予对每个单独会话的访问权限。但是,如果对同一个会话发出两个并发请求(通过使用相同的 SessionID 值),第一个请求将独占访问会话信息。第二个请求只有在第一个请求完成后才执行。(如果信息的排他锁被释放,第二个会话也可以访问,因为第一个请求超过了锁time-out。)如果@Page 指令中的 EnableSessionState 值设置为 ReadOnly,对 read-only 会话信息的请求不会导致对会话数据的独占锁定。但是,read-only 会话数据请求可能仍需要等待 read-write 会话数据请求设置的锁定来清除。
After some more reading, found that requests are processed sequentially if Session is enabled. The session object is a single threaded object. The session object cannot be shared by two threads simultaneously. Hence when there are two requests for the same session one is queued while the session object is in use by the other. This sucks :( Any suggestions, IIS experts? :)
不要使用 Session
。我很少找到证明使用 Session
合理的案例,而且通常很容易找到没有您 运行 所遇到的可扩展性限制的存储替代方案。