7

我正在使用 heroku 来托管一个主要关注托管视频的 Web 应用程序。这些视频是通过 vimeo pro 托管的,我正在使用matthooks 的 vimeo gem来帮助处理上传过程。上传适用于小文件,但不适用于较大的文件(例如~50mb)。

查看 heroku 日志显示我收到 http 错误 413,它代表“请求实体太大”。我相信这可能与 heroku 对文件上传的限制有关(根据此网页,大于 30mb )。但问题是,我能找到的关于该主题的任何信息似乎都已过时且相互冲突(例如声称没有大小限制的此页面)。我在 heroku 的网站上也找不到任何关于此的内容。

我搜索了谷歌并找到了一些相关的页面(),但没有适合我的解决方案。我发现的大多数页面都涉及将大文件上传到亚马逊 s3,这与我想要做的不同。

这是日志的相关输出:

2012-07-18T05:13:31+00:00 heroku[nginx]: 152.3.68.6 - - [18/Jul/2012:05:13:31 +0000]
  "POST /videos HTTP/1.1" 413 192 "http://neoteach.com/components/19" "Mozilla/5.0 
  (Macintosh; Intel Mac OS X 10.7; rv:13.0) Gecko/20100101 Firefox/13.0.1" neoteach.com

日志中没有其他错误。这是我尝试上传太大的视频时出现的唯一输出。这意味着这不是超时错误或超出每个测功机分配的内存的问题。

heroku 真的对上传大小有限制吗?如果是这样,有没有办法改变这个限制?请注意,文件本身根本没有存储在 heroku 的服务器上,它们只是被传递到 vimeo 的服务器上。

如果问题不在于上传大小的限制,那么有人知道还有什么问题吗?

非常感谢!

4

3 回答 3

5

更新:

在这里。我仍然不确定为什么会收到这个特殊的 413 错误,但我能够想出一个使用s3_swf_upload gem 的解决方案。实现涉及闪存,这不太理想,但它是我可以工作的唯一解决方案(我尝试过的 3 或 4 个)。

正如尼尔指出的(感谢尼尔!),我应该得到的错误是“H12 - 请求超时”。经过反复试验,我确实遇到了这个错误。当您尝试从控制器(使用网络测功机)将大文件上传到 heroku 服务器时会出现问题,因为服务器响应发布请求需要很长时间。

正确的方法是将文件直接发送到 s3 而不通过 h​​eroku。

这是我的方法的高级概述:

  1. 使用 s3_swf_upload gem 向 s3 提供直接上传表单。
  2. 使用 gem 中提供的 javascript 回调函数检测文件何时完成上传。
  3. 使用 javascript,向 rails 发送一条消息,让您的服务器知道文件已完成上传。
  4. 响应 javascript 帖子的控制器做了两件事:(a) 将 s3_key 属性分配给视频对象(作为表单中的参数提供)。(b) 使用delayed_job gem 启动后台任务。
  5. 后台任务从 s3 检索文件。我使用aws-sdk gem 来完成此操作,因为它已包含在 s3_swf_upload 中。请注意,这与 aws-s3 gem 明显不同(实际上它们彼此冲突)。
  6. 从 s3 检索文件后,我使用vimeo gem 将其上传到 vimeo(仍在后台)。

上面的实现有效,但并不完美。对于大小接近 500MB 的文件,您仍然会在工作人员测功机中遇到 R14 错误。发生这种情况是因为 heroku 只为每个测功机分配 512MB 的内存,因此您不能一次将整个文件加载到内存中。解决这个问题的方法是在最后一步中实现某种分块,从 s3 中检索文件并将其逐个上传到 vimeo。我仍在这部分工作,我很想听听您的任何建议。

希望这可以帮助某人。有问题尽管问我。就像我说的那样,我的解决方案并不完美,所以如果您认为它可能会更好,请随时添加您自己的答案。

于 2012-07-26T19:10:55.280 回答
3

我认为这里最好的选择确实是直接上传到 S3。与允许用户将文件上传到您自己的服务器(或本例中的 Heroku)相比,它更便宜且更安全。这也是许多视频托管平台使用的经过充分验证的模式(我知道 vzaar 就是这样做的)。

查看 jQuery 上传插件,它允许直接上传到 S3:https ://github.com/blueimp/jQuery-File-Upload

另请查看有关此主题的 Railscast:#381 和 #383。

于 2012-10-30T15:53:59.813 回答
2

您最大的问题不是这里文件的大小,而是您希望用户将大文件上传到 Heroku,然后将它们传递给您。这里的问题是 Heroku 平台上的所有请求都必须在 30 秒内返回第一个字节 - 在您的情况下这不太可能。

因此,您需要考虑让用户直接上传到 S3/Vimeo/任何地方,然后将您的应用程序数据连接到这些上传的资产。

如果您使用的是 Ruby,那么载波直接 gem 可能值得一看它是如何完成的。如果没有第三方服务允许您通过一些代码来执行此操作,您可以将这些代码放入页面中,但这些都需要附加费用。

于 2012-07-18T10:01:02.163 回答