【问题标题】:Can ASP.NET MVC's AsyncController be used to service large number of concurrent hanging requests (long poll)?可以使用 ASP.NET MVC 的 AsyncController 来服务大量并发挂起请求(长轮询)吗?
【发布时间】:2011-06-26 08:31:46
【问题描述】:

Node.js、Tornado 和 Twisted 等框架让开发人员可以创建支持大量并发挂起请求 (10k+) 的服务器推送应用程序。据我了解,他们都是通过不创建线程来服务每个挂起的请求来实现这一点的。

AsyncController 可以用来处理大量不活跃的并发请求吗?

如果是这样,是否有任何相当大的 ASP.NET MVC 网站使用这种方法来创建长轮询应用程序?

【问题讨论】:

  • 这方面有什么进展吗?对于 10k+ 的挂起请求,听起来您需要同时修改 maxWorkerThreadsmaxConcurrentRequestsPerCPU

标签: asp.net asp.net-mvc long-polling server-push asynccontroller


【解决方案1】:

AsyncController 在以下情况下很有用(与普通控制器相比):

您有一个长时间运行的任务,该任务通常由其他层(Web 服务、数据库等)使用I/O Completion Ports 完成。所以请求从一个工作线程开始,然后调用 BeginXXX 方法,该方法将打开一个 IOCP(如果它支持它,如果不支持它就没有用,因为它只会绘制另一个工作线程)并且工作线程将立即返回到线程池。在执行长操作期间,服务器上没有工作线程被消耗。一旦完成它向 IOCP 发出信号,异步控制器就会从池中提取另一个线程来简单地终止请求并将结果返回给视图。这里有几点需要注意:您使用异步控制器而不是普通控制器这一事实对客户端来说绝对没有区别:他仍然需要等待相同的时间才能完成请求,不要误以为异步控制器会使您的慢操作运行得更快。只是工作线程将被独占的时间更短,因此可能会使其他请求运行得更快。

总结一下:对于快速运行的请求,与普通控制器相比,异步控制器不会给您带来任何好处。对于缓慢的请求,它们可以,但这取决于长时间运行的操作的性质以及它是否受 CPU 或 I/O 限制。对于 CPU 绑定的任务,异步控制器也不是更有用。但在所有情况下,您都应该对您的应用程序执行广泛的负载测试。

这是一个very good article on MSDN,它解释了 ASP.NET 中的异步请求。

这里有一个blog post,它说明了如何使用异步控制器来实现长轮询。

【讨论】:

  • 是的,我知道 AsyncControllers 可用于释放工作线程,使其免受长时间运行的 IO 绑定操作的阻塞。取而代之的是,我想知道它们是否可用于保存大量非活动连接(不受 IO 限制或 CPU 限制)。像 Gmail 聊天这样的网站使用长轮询将事件推送到网络浏览器,而不是对它们进行编程以以固定的时间间隔从服务器轮询事件。
  • @David H,我不太明白您所说的控制器持有大量非活动连接是什么意思。为了实现推送功能而不是轮询,您可以使用HTML 5 WebSocket API。如果您在控制器中阻塞或休眠,无论它是异步还是非异步,都非常糟糕。
  • @Darin Dimitrov,这就是我的意思:en.wikipedia.org/wiki/Push_technology#Long_polling 此外,并非所有 Web 浏览器都可以使用 HTML 5 WebSocket。这种技术更像是一种黑客,每个人都在使用它来实现类似的效果。
  • @David H,你可以看看这里:sprklab.com/notes/14-long-polling-comet-in-asp.net
  • @David H,这是一篇博文,说明了如何使用 ASP.NET MVC 异步控制器实现这一目标:clay.lenharts.net/blog/2010/10/19/…
【解决方案2】:

我最近使用基于 great article by Clay Lenhart 的 MVC 3 异步控制器编写了 simple example of a Long Polling Chat Server,但我还没有机会通过一堆连接对其进行真正的测试。

您可以使用我根据BitBucket项目的源设置的example on a AppHarbor deployment

另外,更多信息可从我的blog post explaining the project获得。

【讨论】:

  • 啊,我也做过类似的测试。我将 Node.js 的聊天服务器移植到 ASP.Net MVC 并上传到应用程序港口一段时间:chat.apphb.com 它有我尚未修复的竞争条件。虽然这种技术有效,但我有兴趣知道答案的问题是这种设置是否可以处理 10k+ 用户。 github.com/buddydvd/aspmvc-chatserver
  • 很酷,现在聊天服务器看起来确实很时髦。太糟糕了,C# 不能用 12 行或其他什么来完成,;)。至于并发连接,它似乎会受到 CLR 线程池的限制(嗯,对于我的实现,因为我使用的是 Thread.QueueUserWorkItem)。我将研究如何对其进行负载测试;如果我发现任何有用的东西,我会在这里发布。
  • @Jacob, QueueUserWorkItem 有超过 10k 的挂起请求?工作线程池肯定会很大吗?
  • @bzlm 当然,但必须等待触发发生。您是否有解决此问题的替代方法,尤其是在您投反对票之后?我愿意接受建议。在 .Net 4.0 中,线程池基本上受到内存大小 (stackoverflow.com/questions/2095805/…) 的限制,但我不确定这如何转化为数量以及 10k 对于标准构建服务器来说是否太多。
  • @Jacob,如果只是增加AsyncManager上未完成操作的数量然后返回,然后在触发发生时减少数量,它似乎不会占用线程池线;至少ThreadPool.GetAvailableThreads() 不会改变。不知道它是如何工作的。此外,这里的具体问题(“AsyncController 是否可以用于服务大量不活动的并发请求”)直到您“对如何进行负载测试进行一些研究”才得到回答,是吗? :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-05
  • 2010-12-29
  • 1970-01-01
  • 1970-01-01
  • 2010-11-23
相关资源
最近更新 更多