简体   繁体   English

处理大型下载网站的最佳方式?

[英]Best way to handle a large download site?

I currently have a download site for my school that is based in .net. 我目前在我的学校有一个基于.net的下载站点。 We offer anything from antivirus, autocad, spss, office, and a number of large applications for students to download. 我们提供防病毒,autocad,spss,办公室以及许多大型应用程序供学生下载的任何内容。 It's currently setup to handle them in 1 of 2 ways; 它目前设置为以两种方式之一处理它们; anything over 800 megs is directly accessable through a seperate website while under 800 megs is secured behind .net code using a filestream to feed it to the user in 10,000 byte chunks. 任何超过800兆的东西都可以通过一个单独的网站直接访问,而800兆以下的数据是使用文件流在.net代码后面保护的,以10000字节的形式将其提供给用户。 I have all sorts of issues with feeding downloads this way... I'd like to be able to secure the large downloads, but the .net site just can't handle it, and the smaller files will often fail. 我有这种方式提供下载的各种问题......我希望能够保证大量下载,但.net网站无法处理它,而较小的文件通常会失败。 Is there a better approach to this? 有更好的方法吗?

edit - I just wanted to update on how I finally solved this: I ended up adding my download directory as a virtual directory in iis and specified custom http handler. 编辑 - 我只想更新我最终如何解决这个问题:我最终将我的下载目录添加为iis中的虚拟目录并指定了自定义http处理程序。 The handler grabbed the file name from the request and checked for permissions based on that, then either redirected the users to a error/login page, or let the download continue. 处理程序从请求中获取文件名并根据该权限检查权限,然后将用户重定向到错误/登录页面,或让下载继续。 I've had no problems with this solution, and I've been on it for probably 7 months now, serving files several gigs in size. 我对这个解决方案没有任何问题,我已经使用了大概7个月了,为文件提供了几个大小的演出。

If you are having performance issues and you are delivering files that exist on the filesystem (versus a DB), use the HttpResponse.TransmitFile function. 如果您遇到性能问题并且正在提供文件系统上存在的文件(而不是数据库),请使用HttpResponse.TransmitFile函数。

As for the failures, you likely have a bug. 至于失败,你可能有一个错误。 If you post the code you may be better response. 如果你发布代码,你可能会有更好的回应。

Look into bit torrent. 看看比特洪流。 It's designed specifically for this sort of thing and is quite flexible. 它专为此类设计而设计,非常灵活。

I have two recommendations: 我有两个建议:

  • Increase the buffer size so that there are less iterations 增加缓冲区大小,以减少迭代次数

AND/OR AND / OR

  • Do not call IsClientConnected on each iteration. 不要在每次迭代时调用IsClientConnected。

The reason is that according to Microsoft Guidelines : 原因是根据Microsoft指南

Response.IsClientConnected has some costs, so only use it before an operation that takes at least, say 500 milliseconds (that's a long time if you're trying to sustain a throughput of dozens of pages per second). Response.IsClientConnected有一些成本,所以只能在至少花费500毫秒的操作之前使用它(如果你试图维持每秒几十页的吞吐量,那就很长了)。 As a general rule of thumb, don't call it in every iteration of a tight loop 作为一般经验法则,不要在紧密循环的每次迭代中调用它

Whats wrong with using a robust web server (like Apache) and let it deal with files. 使用强大的Web服务器(如Apache)并让它处理文件是错误的。 Just as you now separate larger files to a webserver, why not serve smaller files the same way too? 正如您现在将较大的文件分离到Web服务器一样,为什么不以相同的方式提供较小的文件?

Is there some hidden requirements to prevent this? 是否有一些隐藏的要求来防止这种情况?

Ok, this is what it currently looks like... 好的,这就是它目前的样子......

    Stream iStream = null;

// Buffer to read 10K bytes in chunk:
byte[] buffer = new Byte[10000];

// Length of the file:
int length;

// Total bytes to read:
long dataToRead;

if (File.Exists(localfilename))
{
    try
    {
        // Open the file.
        iStream = new System.IO.FileStream(localfilename, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);

        // Total bytes to read:
        dataToRead = iStream.Length;

        context.Response.Clear();
        context.Response.Buffer = false;
        context.Response.ContentType = "application/octet-stream";
        Int64 fileLength = iStream.Length;
        context.Response.AddHeader("Content-Length", fileLength.ToString());
        context.Response.AddHeader("Content-Disposition", "attachment; filename=" + originalFilename);

        // Read the bytes.
        while (dataToRead > 0)
        {
            // Verify that the client is connected.
            if (context.Response.IsClientConnected)
            {
                // Read the data in buffer.
                length = iStream.Read(buffer, 0, 10000);

                // Write the data to the current output stream.
                context.Response.OutputStream.Write(buffer, 0, length);

                // Flush the data to the HTML output.
                context.Response.Flush();

                buffer = new Byte[10000];
                dataToRead = dataToRead - length;
            }
            else
            {
                //prevent infinite loop if user disconnects
                dataToRead = -1;
            }
        }
        iStream.Close();
        iStream.Dispose();
    }
    catch (Exception ex)
    {
        if (iStream != null)
        {
            iStream.Close();
            iStream.Dispose();
        }
        if (ex.Message.Contains("The remote host closed the connection"))
        {
            context.Server.ClearError();
            context.Trace.Warn("GetFile", "The remote host closed the connection");
        }
        else
        {
            context.Trace.Warn("IHttpHandler", "DownloadFile: - Error occurred");
            context.Trace.Warn("IHttpHandler", "DownloadFile: - Exception", ex);
        }
        context.Response.Redirect("default.aspx");
    }
}

There's a lot of licensing restrictions... for example we have an Office 2007 license agreement that says any technical staff on campus can download and install Office, but not students. 存在许多许可限制......例如,我们有Office 2007许可协议,该协议表明校园内的任何技术人员都可以下载和安装Office,但不能学生。 So we don't let students download it. 所以我们不要让学生下载它。 So our solution was to hide those downloads behind .net. 所以我们的解决方案是将这些下载隐藏在.net之后。

Amazon S3 sounds ideal for what you need, but it is commercial service and fileas are served from their servers. Amazon S3听起来非常适合您的需求,但它是商业服务,文件服务器提供服务。

You should try to contact amazon and ask for academic pricing. 您应该尝试联系亚马逊并要求学术定价。 Even if they don't have one. 即使他们没有。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM