【问题标题】:How to limit number of concurrent file downloads for the number of requests?如何限制请求数的并发文件下载数?
【发布时间】:2011-10-13 09:04:39
【问题描述】:

我创建了一个 MVC.Net 应用程序,并且有一个下载页面,用户可以从中下载大约 5MB 大小的安装文件。当我们点击下载按钮时,这个设置文件是动态生成的。此设置文件的每次动态生成都会增加 7% 的服务器 CPU 使用率。 假设用户数量增加至少 100 并且所有用户都将尝试下载文件,那么 CPU 使用率将增加到 100%,这将导致服务器停机或无响应。

为了克服这种情况,我们试图通过代码在逻辑上限制一次总共 5 次下载。这意味着一次可以有 5 个用户下载文件,第 6 个以后的用户将排队,直到前 5 个下载未完成。此外,我们必须向排队的用户显示“您的下载将在 28 秒后开始”左右的等待时间。

任何关于如何实现这一目标的建议都将受到高度赞赏。

问候, 海达尔

【问题讨论】:

  • 可能有多少个不同版本的设置?您是否总是需要动态生成它?
  • 版本将针对每个用户,这需要动态生成。
  • 您不能注册一个异步方法或服务来将这些文件分发排队 - 然后在准备好时向用户发送电子邮件链接以下载文件?我想你可以有一个服务,在 24-48 小时后删除生成的文件。

标签: jquery asp.net sql-server asp.net-mvc


【解决方案1】:

您可以使用 Semaphore 并将其限制为 5 个。您可以在静态类中维护 Semaphore 并由您的控制器访问它。

这里是一个例子:

public static class MySemaphore {
  private static Semaphore pool = new Semaphore(0,5);
  public Semaphore GetSemaphore() { return pool; }
}

public class MyController : Controller {
  public ActionResult MyDownloadAction() {
    MySemaphore.GetSemaphore().WaitOne(); // wait for semaphore
    // do your job : create file
    // ...
    MySemaphore.GetSemaphore().Release(); // release the semaphore
    // prepare download resource and send response
    // ...
    return View();
  }

}

【讨论】:

  • 如果有 5 个请求正在处理,这将阻止第 6 个请求并可能导致客户端超时。虽然在语义上是正确的,但问题中描述的用户体验是不同的。
【解决方案2】:

您描述的行为要求您从操作中返回,然后使用 AJAX 跟踪请求状态。

在简单的幼稚方法中,这意味着当请求进来时,您将发出一张票并返回一个告诉用户等待的页面,而不是返回文件结果。

返回给用户的票可以在 cookie 中,也可以在页面本身中。就值而言,您可以使用 GUID。

然后页面将每隔 n 秒使用 AJAX 轮询您的服务器。理想情况下,此轮询应更新服务器端的票证(例如最后检查的时间戳),以便您知道仍有用户在等待票证送达。一旦你有能力,你将为 AJAX GET 返回一个结果,告诉页面 JS 代码开始下载。

如果您的票证不在 cookie 中,您可以在此处将票证添加到请求 URL。

在服务器端,您将检查票证,确保票证有效且订购正确,然后提供文件并删除票证。

现在这么说,实施细节将取决于您计划拥有多少台服务器。如果您想拥有一个可扩展的系统,那么我建议您使用诸如 Web Role/Worker Role/Queue of azure 之类的东西。通过这种方式,您将解耦出票、票证跟踪和票证处理。

对于概念验证系统,您可以将票证保存在内存中,或者对于小型多机系统,您可以拥有一个共享数据库。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-09
    • 2019-07-31
    • 1970-01-01
    • 2017-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多