【问题标题】:ASP.Net MVC Delayed requests arriving long after client browser closedASP.Net MVC 延迟请求在客户端浏览器关闭后很长时间到达
【发布时间】:2015-03-25 13:29:35
【问题描述】:

我想我知道这里发生了什么,但希望得到确认和/或阅读材料,可以将“思考”变成“知道”,在 Tl,DR 部分的帖子末尾有实际问题:

场景:

我正在测试我的 MVC 应用程序,以解决其中一个内部组件停止运行(连接到我们的数据库时超时)的情况。

在我的一个网页上有一个 Jquery 数据表,它每半秒通过 ajax 查询一次更新 - 我当前的任务是在数据请求超时时显示正确的错误。所以为了测试,我创建了一个存储过程,要求数据库服务器在响应前等待 3 秒,这比配置的超时设置长 - 所以这保证了我可以捕获超时异常。

我正在 Chrome 浏览器中进行测试,一个客户端。 VS2013 IIS Express中正在调试应用程序

问题: 没想到激活故意减速后会出现以下症状:

1) 启动带有操纵数据表的页面后,应用程序在处理来自客户端浏览器的所有请求时变慢了 - 还有 3 个其他组件发送 ajax 更新请求,与我故意破坏的组件并行,这同样减慢也适用于我在 Web 应用程序中所做的任何会生成请求的操作(例如导航到其他页面)。浏览器的调试器显示请求正在按时发送,但服务器端的相应断点被击中要晚得多(延迟超过 10 秒甚至几分钟)

2) 即使在我关闭应用程序的选项卡后,我的服务器仍在处理请求。我关闭了浏览器,我确保 chrome.exe 进程已终止,但在 20 分钟后,各种控制器操作上的断点仍然受到攻击 - 主要是通过自动循环来自几个页面的 ajax 请求“触发”的操作我在我的测试期间试图访问。在我试图导航到的主页上也遇到了断点。在第二次测试中,我使用 RawCap 监控环回接口,以确保实际上没有任何东西在后台运行请求。

我想用另一种解释确认或否认的理论:

因此,上述场景是以服务器无法处理的频率发出循环请求 - 客户端数据表循环每 0.5 秒发送一次,每个请求至少需要 3 秒才能生成超时。显然,在 IIS express 的某个地方,它必须限制它能够处理的并发请求的数量......

让我感到惊讶的是,我有点假设如果达到了该限制(我也假设存在),那么请求将被拒绝 - 相反,它们似乎排队等待绝对无用的时间稍后处理 - 我的意思是,在什么情况下半小时后处理排队的 Web 请求会有用?

所以到目前为止我的问题是:

Tl,DR 问题:

IIS Express(Visual Studio 2013 附带)是否有并发连接限制?

如果是: { 这个限制是否可以在某个地方配置,如果可以,在哪里?

IIS express 如何处理达到该限制的情况 - 这种处理是否也可以在某处进行配置? (我的意思是像排队和即时错误,比如服务器很忙) }

如果没有: { 当请求来得快于处理速度时,服务器如何处理场景,并且可以在任何地方配置该处理吗? }

这里 - http://www.iis.net/learn/install/installing-iis-7/iis-features-and-vista-editions

我发现 IIS7 至少允许无限数量的同时连接,但是如果服务器的速度不足以处理所有请求,这实际上是如何工作的?可以在任何地方配置限制,以及处理达到的限制吗?

如果有任何上述在线阅读材料的链接,我们将不胜感激。

【问题讨论】:

    标签: asp.net asp.net-mvc iis concurrency iis-express


    【解决方案1】:

    首先,这是一个简短的 Web 服务器 101。生产级 Web 服务器是多线程的,大致一个线程 = 一个请求。您通常会看到您的 Web 服务器的某种设置,称为“最大请求数”,这再次大致对应于它可以生成的线程数。每个线程在 CPU 和 RAM 方面都有开销,因此考虑到运行它的机器所拥有的资源,一个 Web 服务器可以生成多少个非常实际的上限。

    当 Web 服务器达到此限制时,它不会开始拒绝请求,而是将请求排队等待线程释放后处理。例如,如果 Web 服务器的最大请求数为 1000(典型值),但它突然被 1500 个请求轰炸。前 1000 个将被立即处理,接下来的 500 个将排队等待一些初始请求得到响应,从而释放线程并允许处理一些排队的请求。

    这里的一个相关主题领域是异步,它在 Web 应用程序的上下文中允许线程在处于等待状态时返回到“池”。例如,如果您正在与 API 通信,则在发送请求和从 API 获得响应之间会有一段时间的等待,通常是由于网络延迟。如果您异步处理,那么在此期间,线程可以返回到池中以处理其他请求(例如前面示例中的 500 个排队请求)。当 API 最终响应时,将返回一个线程来完成对请求的处理。异步允许服务器通过使用本来空闲的线程来更有效地处理资源来处理新请求。

    然后是客户端-服务器的概念。在 HTTP 等协议中,客户端发出请求,服务器响应该请求。但是,两者之间没有持久的联系。 (这在 HTTP 1.1 中有些不真实。客户端和服务器之间的连接有时会保持不变,但这只是为了允许更快的未来请求/响应,因为启动连接所花费的时间不是一个因素。但是,没有在这种情况下,关于客户端/服务器状态的真正持久通信仍然存在)。这里的要点是,如果客户端(如 Web 浏览器)向服务器发送请求,然后关闭客户端(例如关闭浏览器中的选项卡),则该事实不会传达给服务器。服务器所知道的是它收到了一个请求并且必须响应,并且它会响应,即使从技术上讲,另一端没有任何东西可以接收它。换句话说,仅仅因为浏览器选项卡已经关闭,并不意味着服务器会停止处理请求并继续前进。

    然后有超时。客户端和服务器都会有一些他们会遵守的超时值。 Internet 的分布式特性(由 TCP/IP 和 HTTP 等协议启用)意味着网络中的节点被假定为瞬态的。没有持久连接(除了上面的相同注释),并且在发出请求的客户端和响应请求的服务器之间可能会发生网络中断。如果客户端/服务器没有为此计划,他们可以简单地坐在那里永远等待。但是,这些超时可以有很大的不同。服务器通常会在 30 秒内响应请求超时(尽管它可能会无限期设置)。像网络浏览器这样的客户端往往更宽容一些,在某些情况下超时时间为 2 分钟或更长时间。当服务器超时时,请求将被中止。根据为什么发生超时,客户端可能会收到各种错误响应。但是,当客户端超时时,通常不会通知服务器。这意味着如果服务器的超时时间高于客户端的超时时间,服务器继续尝试响应,即使客户端已经移动。关闭浏览器选项卡可以被认为是客户端立即超时,但同样,服务器并不明智,并且继续尝试完成它的工作。

    所以,这一切归结为这个。首先,在进行长轮询时(这是您通过每隔一段时间重复提交 AJAX 请求所做的事情),您需要构建一个取消方案。例如,如果最后 5 个请求已超时,您应该至少停止轮询一段时间。更好的是让一个 AJAX 请求的响应启动下一个。因此,您可以使用setTimeout 并让AJAX 回调启动它,而不是使用setInterval 之类的东西。这样,只有在链未中断的情况下,请求才会继续。如果一个 AJAX 请求失败,轮询会立即停止。但是,在这种情况下,您可能需要一些回退来在一段时间后重新启动请求链。这可以防止用新的请求无休止地轰炸你已经失败的服务器。此外,应该始终对应该继续进行轮询的时间进行一些向上限制。如果用户将选项卡打开几天而不使用它,您真的应该一直轮询服务器吗?

    在服务器端,您可以使用带有取消令牌的异步。这做了两件事:1)它为您的服务器提供了更多的喘息空间来处理更多请求;2)它提供了一种在请求的某些部分超时时解除请求的方法。有关这方面的更多信息,请访问:http://www.asp.net/mvc/overview/performance/using-asynchronous-methods-in-aspnet-mvc-4#CancelToken

    【讨论】:

    • 感谢您的解释和链接。我实际上正在切换我们的客户端以使用 setTimeout 来获取 AJAX 请求的响应。我发布了这个问题作为一种署名确认我正在尝试做的这个解决方案实际上是正确的,因为我不确定请求排队。
    猜你喜欢
    • 1970-01-01
    • 2022-07-29
    • 1970-01-01
    • 2021-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    • 1970-01-01
    相关资源
    最近更新 更多