2012-07-18 95 views
5

我正在使用heroku主持託管視頻的主要焦點的Web應用程序。這些視頻是通過vimeo pro託管的,我使用vimeo gem by matthooks來幫助處理上傳過程。 上傳適用於小文件,但不適用於較大文件(例如〜50mb)。如何在Heroku上上傳大文件(特別是視頻)

看一看heroku日誌顯示我得到http錯誤413,它代表「Request Entity Too Large」。我相信這可能與heroku對文件上傳的限制(大於30mb,according to this webpage)有關。但問題是,我可以找到關於這個問題的任何信息似乎是過時的和衝突的(就像這個頁面claims there is no size limit)。我也無法在heroku的網站上找到關於此的任何內容。

我搜索谷歌,發現一些有點相關的網頁(onetwo),但沒有解決方案,爲我工作。我找到的大部分網頁都是將大文件上傳到亞馬遜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的服務器。

如果問題不限制上傳大小,是否有人知道還有什麼可能會出錯?

非常感謝!

+0

據我所知,沒有這樣的方式。我不得不直接上傳到S3。您可能會找到某種方式將視頻直接傳遞給Vimeo,但我發現的唯一結果並不令人鼓舞:http://vimeo.com/forums/topic:28113 – Qsario 2012-07-18 05:50:56

+0

值得注意的是,我剛剛測試過上傳一個8.5MB的文件到我的Heroku應用程序,花了3分15秒(是的,我有DSL)。我在'Procfile'中有'web:gunicorn -t 60 -k「eventlet」-w 3 myapp.wsgi:application'。換句話說,我將超時時間增加到了60秒,而我的應用程序將允許上傳時間超過3分鐘。我不確定這個原因,但它與我的Dyno允許併發連接有關。 – orokusaki 2013-11-04 16:22:12

回答

4

更新:這裏

OP。我仍然不確定爲什麼我會得到這個特殊的413錯誤,但是我能夠想出一個使用s3_swf_upload寶石的解決方案。這個實現涉及閃存,這不太理想,但它是我能夠工作的唯一解決方案(我嘗試過的3或4)。 Neil指出(謝謝Neil!),我應該得到的錯誤是「H12 - 請求超時」。經過多次試驗,我最終遇到了這個錯誤。當您嘗試從控制器上將大文件上傳到heroku服務器(使用Web dyno)時會發生此問題,因爲服務器響應帖子請求所用的時間太長。

正確的做法是直接發送文件到s3而不通過heroku。

這裏是我的方法的高度概括:

  1. 使用s3_swf_upload寶石提供一個直接上傳表格S3。
  2. 檢測文件何時完成上傳與在寶石中提供的JavaScript回調函數。
  3. 使用javascript,發送一條信息讓你的服務器知道文件已經完成上傳。
  4. 響應javascript post的控制器會做兩件事:(a)爲視頻對象分配一個s3_key屬性(在表單中作爲參數提供)。 (b)使用delayed_job寶石啓動後臺任務。
  5. 後臺任務從s3中檢索文件。我使用了aws-sdk寶石來實現這一點,因爲它已經包含在s3_swf_upload中。 請注意,這與aws-s3寶石截然不同(事實上它們相互衝突)。
  6. 從s3檢索到文件後,我使用vimeo gem將其上傳到vimeo(仍在後臺)。

上面的工作實現,但它不是完美的。對於接近500MB大小的文件,您仍然會在您的工作人員dynos中遇到R14錯誤。發生這種情況的原因是,heroku每個動態碼只能分配512MB的內存,因此無法一次將整個文件加載到內存中。解決這個問題的方法是在最後一步中實現某種分塊,從s3中檢索文件並將其上傳到vimeo。我仍在研究這一部分,我很樂意聽到您可能提出的任何建議。

希望這可能有助於某人。有問題儘管問我。就像我說的,我的解決方案並不完美,所以如果您認爲它可能會更好,請隨時添加您自己的答案。

+0

看看帶有「霧」和「CarrierwaveDirect」的「Carrierwave」 – Narfanator 2013-02-12 01:30:10

+0

這很有幫助,謝謝! – 2015-08-11 23:10:10

2

您最大的問題不在於這裏的文件大小,而是您希望用戶上傳大文件到Heroku,然後傳遞它們。這裏的問題是,Heroku平臺上的所有請求必須在30秒內返回第一個字節 - 在您的情況下,這是不太可能的。

因此,您需要考慮讓用戶直接上傳到S3/Vimeo/whereever,然後將您的應用程序數據連接到這些上傳的資產。

如果您使用的是Ruby,那麼運營商直接創業板可能值得一看。如果沒有第三方服務,那麼您可以通過一些可以放入頁面的代碼來執行此操作,但這些代碼會附帶一些附加成本。

+0

謝謝尼爾, 我上面描述的問題似乎並沒有超時。日誌中沒有「H12 - 請求超時」。不過,我知道超時文件上傳會帶來很大風險,所以我會研究直接上傳。也許這也將解決上述問題。 – stephenalexbrowne 2012-07-18 14:26:04

+0

它應該。我猜你到目前爲止一直在測試一個體面的連接。 – 2012-07-18 16:17:33

+0

只有當連接閒置30秒纔會超時。 – 2012-07-18 17:04:16

2

我認爲這裏最好的選擇的確是直接上傳到S3。它比允許用戶將文件上傳到自己的服務器(或者在這種情況下是Heroku)要便宜得多,安全得多。這也是許多視頻託管平臺所使用的一個成熟的模式(我知道vzaar做到這一點)。

退房jQuery的上傳插件,它可以直接上傳到S3:https://github.com/blueimp/jQuery-File-Upload

還檢查了Railscasts圍繞這個話題:#381和#383。