将多个 HTTP 请求等待同一个 I/O 完成端口

Posted

技术标签:

【中文标题】将多个 HTTP 请求等待同一个 I/O 完成端口【英文标题】:Put several HTTP request to wait for the same I/O completion port 【发布时间】:2011-11-28 17:17:17 【问题描述】:

我的应用程序从 Web 服务和“Application_Start”异步加载大量信息。

如果用户请求想要使用该信息,但它还没有准备好,线程将被 Monitor.Wait 阻塞。当信息准备好后,缓存对象会Monitor.Pulse所有等待的线程。这应该没问题,因为信息需要十几秒钟,并且必须将用户重定向到登录页面,发布登录信息,然后再次重定向。

问题是 Monitor.Wait 会阻塞 CLR ThreadPool 线程,据我所知,如果有大量请求到达并要求“大信息”,应用程序可能会被 CLR ThreadPool 饥饿阻塞(我有与当前的 IIS/ASP.NET 线程门控有点混乱)。

由于大量信息来自我异步调用的 Web 服务,因此我拥有该操作的 IAsyncResult。

那么,有没有办法告诉 CLR ThreadPool 线程“等待这个 IOCP”,以便线程池线程可以开始参加其他调用?

我觉得这没有很好的解释,如果不清楚我在问什么,请告诉我。

问候。

PS:虽然赏金已经结束,但如果有人知道如何做到这一点,我会提出一个新的并授予作者。

【问题讨论】:

+1 是一个很好且解释清楚的问题。您的应用程序的所有页面都需要此信息还是只需要其中一些信息?第一个请求总是到达特定页面还是可以是任何页面? 谢谢。只有一些页面需要此信息。考虑到一个关闭的应用程序域,并且第一个请求强制 IIS 启动它,第一个请求将未经身份验证(因为我们在 Session 对象中保留了一些小的登录信息),所以第一个页面将是登录页面。 【参考方案1】:

这是一个很好的问题。我的经验是,您尝试干扰 ASP.NET 内部的次数越多,造成的痛苦就越多。

您是否考虑过使用serviceAutoStartProviders 来保持您的应用程序热度?

ASP.NET 4.0: How to use application warm-up class

【讨论】:

这很有趣。但是,如果预热逻辑需要很长时间会发生什么?在此期间没有人回答请求?也许保留应用程序池将是解决方案,但有什么方法可以告诉 IIS 保持一个始终处于活动状态? 很难说,这类事情要因人而异。在你把它弄好之前需要一些试验和错误。【参考方案2】:

您应该使用IHttpAsyncHandler 来返回加载缓慢的大数据。 Walkthrough: Creating an Asynchronous HTTP Handler

在处理异步 HTTP 处理程序期间,ASP.NET 将 通常用于外部进程的线程 进入线程池,直到处理程序收到来自 外部进程。这样可以防止线程阻塞并提高 性能,因为只能执行有限数量的线程 同时。

花 12 秒从IHttpAsyncHandler 返回应该没有问题。事实上,您应该能够轻松地达到大约 60 秒,而不必担心。除此之外,您可能需要实现某种类型的long-polling 系统来监控系统状态。

IHttpAsyncHandler 可以返回 XML/JSON 或任何你喜欢的。如果您想使用 HttpWebRequest(一些示例 C# 代码:Calling remote JSON webservice),您可以通过 ajax 在 javascript(可能是 jQuery.ajax)甚至服务器端使用 IHttpAsyncHandler。

【讨论】:

我已经在 MVC 中使用 AsyncController,并且我已经有一个代表 IOCP 的 IAsyncResult,我想要告诉两个或多个请求等待该 IOCP 而无需旋转等待,因为数据是很常见,我不想多次检索它。 @vtortola 然后,您应该在 MVC 应用程序的内存中缓存数据并提供缓存的副本。这意味着您可以有多个 IAsyncResults 等待缓存仅检索一次数据。这个问题真的应该是关于缓慢的大数据应用程序架构,而不是关于 IOCP。您不想弄乱服务器的基础,尤其是如果您可以通过常用方式完成任务。

以上是关于将多个 HTTP 请求等待同一个 I/O 完成端口的主要内容,如果未能解决你的问题,请参考以下文章

检索具有多个重叠 I/O 请求的缓冲区

Socket编程模型之完成端口模型

HTTP 之 MPM工作模式

Java NIO Channel之FileChannel [ 转载 ]

I/O 完成端口,如何释放每个套接字上下文和每个 I/O 上下文?

将多个文件关联到同一个 io 完成端口,同时保持文件流顺序 c#