什么是最好的办法来处理这个:大型下载通过PHP +缓慢的连接从客户端=脚本超时,文件被完全下载之前 [英] What is the best way to handle this: large download via PHP + slow connection from client = script timeout before file is completely downloaded

查看:177
本文介绍了什么是最好的办法来处理这个:大型下载通过PHP +缓慢的连接从客户端=脚本超时,文件被完全下载之前的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的客户想要一种方式为用户提供下载,但只有在他们填写注册表单(基本上是名称和电子邮件)后。向用户发送具有用于可下载内容的链接的电子邮件。链接包含对包,文件和用户唯一的注册哈希,他们实际上去一个PHP页面,记录每个下载,并通过写入到stdout(以及相应的头文件)来推出文件这个解决方案有固有的缺陷,但这是他们想要做的,它需要说,我把他们努力到1.)限制可下载文件的大小和2.)考虑使用CDN(他们有国际客户,但托管在美国在2个镜像服务器和使用粘性IP的负载平衡器)。无论如何,它为我工作,但他们的一些国际客户是真正缓慢的连接(d / l速率〜60kB /秒),其中一些文件是相当大(150 MB)。由于这是一个提供这些文件的PHP脚本,它受脚本超时设置的约束。起初我设置为300秒(5分钟),但这不是一些测试用户的时间。所以,我试图根据文件的大小除以100kb / sec连接计算脚本超时,但其中一些用户甚至比这更慢。

My client wanted a way to offer downloads to users, but only after they fill out a registration form (basically name and email). An email is sent to the user with the links for the downloadable content. The links contain a registration hash unique to the package, file, and user, and they actually go to a PHP page that logs each download and pushes the file out by writing it to stdout (along with the appropriate headers. This solution has inherent flaws, but this is how they wanted to do it. It needs to be said that I pushed them hard to 1.) limit the sizes of the downloadable files and 2.) think about using a CDN (they have international customers but are hosted in the US on 2 mirrored servers and a load balancer that uses sticky IPs). Anyway, it "works for me" but some of their international customers are on really slow connections (d/l rates of ~60kB/sec) and some of these files are pretty big (150 MB). Since this is a PHP script that is serving these files, it is bound by the script timeout setting. At first I had set this to 300 seconds (5 minutes), but this was not enough time for some of the beta users. So then I tried calculating the script timeout based on the size of the file divided by a 100kb/sec connection, but some of these users are even slower than that.

现在客户端只想提高超时值。我不想一起删除超时,以防脚本以某种方式进入无限循环。我也不想继续推出超时任意的一些全部最低共同分母连接速率(大多数人下载比100kb /秒)。我也想在某个时候告诉客户端看,这些文件太大,无法处理这种方式。你用这些40多分钟的连接影响网站的其余部分的性能我们需要重新思考如何交付或使用更小的文件。

Now the client wants to just up the timeout value. I don't want to remove the timeout all together in case the script somehow gets into an infinite loop. I also don't want to keep pushing out the timeout arbitrarily for some catch-all lowest-common-denominator connection rate (most people are downloading much faster than 100kb/sec). And I also want to be able to tell the client at some point "Look, these files are too big to process this way. You are affecting the performance of the rest of the website with these 40-plus minute connections. We either need to rethink how they are delivered or use much smaller files."

我有几个解决方案,如下:

I have a couple of solutions in mind, which are as follows:


  1. CDN - 将文件移动到CDN服务,如亚马逊或谷歌。我们仍然可以通过PHP文件记录下载尝试,但然后将浏览器重定向到真实文件。这样做的一个缺点是,用户可以绕过脚本并且一旦他们具有URL(可以通过观看HTTP头部收集)直接从CDN下载。

  2. 展开服务器群 - 将服务器群从2扩展到4个以上的服务器,并删除粘性IP规则从负载均衡器。下载:这些是Windows服务器,因此它们是昂贵的。没有理由为什么他们不能是Linux盒子,但是设置所有新的盒子可能需要比客户允许的更多的时间。

  3. 设置2个新服务器严格服务这些下载 - 基本上与#2相同的优点和缺点,除了我们可以至少将网站的其余部分与这个特定进程隔离开来(并且微调新服务器)。

  4. 检测用户的连接速率 - 我想到了一种方法,可以通过使用以下方式检测用户的当前速度: AJAX在下载登录页面上的时间下载一个已知文件大小的静态文件所需的时间,然后发送该信息到服务器,并根据该信息计算超时。这不是理想的,但它比估计连接速度太高或太低要好。我不知道如何将速度信息返回到服务器,因为我们目前使用的是从服务器发送的重定向标头。

  1. CDN - move the files to a CDN service such as Amazon's or Google's. We can still log the download attempts via the PHP file, but then redirect the browser to the real file. One drawback with this is that a user could bypass the script and download directly from the CDN once they have the URL (which could be gleaned by watching the HTTP headers). This isn't bad, but it's not desired.
  2. Expand the server farm - Expand the server farm from 2 to 4+ servers and remove the sticky IP rule from the load balancer. Downside: these are Windows servers so they are expensive. There is no reason why they couldn't be Linux boxes, but setting up all new boxes could take more time than the client would allow.
  3. Setup 2 new servers strictly for serving these downloads - Basically the same benefits and drawbacks as #2, except that we could at least isolate the rest of the website from (and fine tune the new servers to) this particular process. We could also pretty easily make these Linux boxes.
  4. Detect the users connection rate - I had in mind a way to detect the current speed of the user by using AJAX on the download landing page to time how long it takes to downloading a static file with a known file size, then sending that info to the server and calculating the timeout based on that info. It's not ideal, but it's better than estimating the connection speed too high or too low. I'm not sure how I would get the speed info back to the server though since we currently use a redirect header that is sent from the server.

机会是#的1-3将被拒绝或至少推迟。因此,4是一个很好的方法来解决这个问题,还是有其他我没有考虑过的?

Chances are #'s 1-3 will be declined or at least pushed off. So is 4 a good way to go about this, or is there something else I haven't considered?

(随意挑战原始解决方案。)

(Feel free to challenge the original solution.)

推荐答案

使用X-SENDFILE。大多数网络服务器会通过本机或插件(apache)来支持它。

Use X-SENDFILE. Most webservers will support it either natively, or though a plugin (apache).

使用这个头文件你可以简单的指定一个本地文件路径并退出PHP脚本。网络服务器查看标题并改为提供该文件。

using this header you can simply specify a local file path and exit the PHP script. The webserver sees the header and serves that file instead.

这篇关于什么是最好的办法来处理这个:大型下载通过PHP +缓慢的连接从客户端=脚本超时,文件被完全下载之前的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆