如何限制请求数量的并发文件下载次数?

时间:2011-10-13 09:04:39

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

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

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

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

此致 海德尔

2 个答案:

答案 0 :(得分: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();
  }

}

答案 1 :(得分:0)

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

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

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

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

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

在服务器端,您将检查故障单,确保其有效并正确订购,并提供该文件并删除故障单。

现在说这个,实施细节将取决于您计划拥有多少台服务器。如果你想拥有一个可扩展的系统,那么我建议使用像Azure角色/工作者角色/队列这样的东西。这样,您将解除票证发放,票证跟踪和票证处理。

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