2012-07-18 19 views
5

Tôi đang sử dụng heroku để lưu trữ ứng dụng web với trọng tâm chính là lưu trữ video. Các video được lưu trữ thông qua vimeo pro và tôi đang sử dụng vimeo gem by matthooks để giúp xử lý quá trình tải lên. Tải lên các tác phẩm cho các tệp nhỏ, nhưng không cho các tệp lớn hơn (ví dụ: ~ 50mb).Cách tải các tệp lớn lên Heroku (đặc biệt là video)

Nhìn vào nhật ký heroku cho thấy tôi nhận được lỗi http 413, viết tắt của "Yêu cầu thực thể quá lớn". Tôi tin rằng điều này có thể phải làm với giới hạn mà heroku đặt lên các tệp tải lên (lớn hơn 30mb, according to this webpage). Vấn đề là mặc dù bất kỳ thông tin nào tôi có thể tìm thấy về chủ đề này dường như đã lỗi thời và xung đột (như trang này là claims there is no size limit). Tôi cũng không thể tìm thấy bất cứ điều gì trên trang web của heroku về điều này.

Tôi đã tìm kiếm trên google và tìm thấy một số trang có liên quan phần nào (onetwo), nhưng không có giải pháp nào phù hợp với tôi. Hầu hết các trang mà tôi tìm thấy đều giải quyết việc tải các tệp lớn lên amazon s3, khác với những gì tôi đang cố gắng thực hiện.

Dưới đây là kết quả có liên quan của các bản ghi:

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 

Không có lỗi khác trong các bản ghi. Đây là sản lượng duy nhất xuất hiện khi tôi cố gắng tải video lên quá lớn. Điều này có nghĩa rằng đây không phải là lỗi hết thời gian chờ hoặc sự cố vượt quá bộ nhớ được phân bổ cho mỗi dyno.

Heroku có thực sự đặt giới hạn về kích thước tải lên không? Nếu vậy, có cách nào để thay đổi giới hạn này không? Lưu ý rằng bản thân các tập tin không được lưu trữ trên các máy chủ của Heroku, chúng chỉ đơn thuần được truyền cho các máy chủ của vimeo.

Nếu vấn đề không phải là giới hạn về kích thước tải lên, có ai có ý tưởng về điều gì khác có thể xảy ra không?

Cảm ơn nhiều!

+0

Theo như tôi biết, không có cách nào như vậy. Tôi phải tải trực tiếp lên S3. Bạn có thể tìm thấy một số cách để truyền video trực tiếp cho Vimeo, nhưng kết quả duy nhất tôi tìm thấy không phải là rất đáng khích lệ: http://vimeo.com/forums/topic:28113 – Qsario

+0

Đáng chú ý, tôi vừa thử nghiệm tải một tệp 8.5MB lên ứng dụng Heroku của tôi, mất 3 phút và 15 giây (có, tôi có DSL). Tôi có 'web: gunicorn -t 60 -k" eventlet "-w 3 myapp.wsgi: application' trong' Procfile' của tôi. Nói cách khác, tôi đã tăng thời gian chờ lên 60 giây và ứng dụng của tôi sẽ cho phép tải lên mất hơn 3 phút. Tôi không chắc chắn lý do cho điều này, nhưng nó có một cái gì đó để làm với Dyno của tôi cho phép kết nối đồng thời. – orokusaki

Trả lời

4

Cập nhật:

OP đây. Tôi vẫn không chắc chắn lý do tại sao tôi đã nhận được lỗi này đặc biệt 413, nhưng tôi đã có thể đưa ra một giải pháp hoạt động bằng cách sử dụng đá quý s3_swf_upload. Việc thực hiện liên quan đến flash, đó là ít hơn lý tưởng, nhưng nó là giải pháp duy nhất (trong số 3 hoặc 4 mà tôi đã cố gắng) mà tôi có thể làm việc.

Như Neil đã chỉ ra (cảm ơn Neil!), Lỗi tôi cần phải nhận được là "H12 - Yêu cầu thời gian chờ". Và cuối cùng tôi đã gặp phải lỗi này sau nhiều lần thử nghiệm lặp đi lặp lại.Vấn đề xảy ra khi bạn cố tải các tệp lớn lên máy chủ heroku từ bộ điều khiển của bạn (sử dụng một web dyno), vì phải mất quá nhiều thời gian để máy chủ phản hồi yêu cầu đăng bài.

Cách tiếp cận thích hợp là gửi tệp trực tiếp đến s3 mà không phải chuyển qua heroku.

Dưới đây là một tổng quan cấp cao của phương pháp của tôi:

  1. Sử dụng đá quý s3_swf_upload để cung cấp một hình thức upload trực tiếp cho s3.
  2. Phát hiện khi tệp được tải lên xong bằng chức năng gọi lại javascript được cung cấp trong đá quý.
  3. Sử dụng javascript, gửi đường ray một tin nhắn đăng để cho phép máy chủ của bạn biết tệp được tải lên xong.
  4. Bộ điều khiển phản hồi bài đăng javascript thực hiện hai việc: (a) gán thuộc tính s3_key cho đối tượng video (được phân phối dưới dạng tham số trong biểu mẫu). (b) khởi tạo tác vụ nền bằng cách sử dụng đá quý delayed_job.
  5. Tác vụ nền truy xuất tệp từ s3. Tôi đã sử dụng đá quý aws-sdk để thực hiện điều này, vì nó đã được bao gồm trong s3_swf_upload. Lưu ý rằng điều này khác biệt rõ rệt so với đá quý aws-s3 (trên thực tế chúng xung đột với nhau).
  6. Sau khi tệp được lấy từ s3, tôi đã sử dụng đá quý vimeo để tải lên vimeo (vẫn ở chế độ nền).

Triển khai ở trên hoạt động, nhưng không hoàn hảo. Đối với các tệp có kích thước gần 500MB, bạn vẫn sẽ gặp phải lỗi R14 trong dynos công nhân của mình. Điều này xảy ra bởi vì heroku chỉ phân bổ 512MB bộ nhớ cho mỗi dyno, vì vậy bạn không thể tải toàn bộ tệp vào bộ nhớ cùng một lúc. Cách xung quanh vấn đề này là để thực hiện một số loại chunking trong bước cuối cùng, nơi bạn lấy các tập tin từ s3 và tải nó lên vimeo từng mảnh. Tôi vẫn đang làm việc về phần này, và tôi rất muốn nghe bất kỳ đề xuất nào bạn có thể có.

Hy vọng điều này có thể giúp ai đó. Hãy hỏi tôi bất kỳ câu hỏi. Như tôi đã nói, giải pháp của tôi không hoàn hảo nên bạn có thể tự do thêm câu trả lời của riêng mình nếu bạn nghĩ nó có thể tốt hơn.

+0

Nhìn vào "Carrierwave" với "Fog" và "CarrierwaveDirect" – Narfanator

+0

Thật hữu ích, cảm ơn! –

2

Vấn đề lớn nhất của bạn không phải là kích thước của các tệp ở đây, nhưng thực tế là bạn đang mong đợi người dùng tải tệp lớn lên Heroku và sau đó truyền chúng lên. Vấn đề ở đây là tất cả các yêu cầu trên nền tảng Heroku phải trả về byte đầu tiên trong vòng 30 giây - trong trường hợp của bạn là rất khó xảy ra.

Vì vậy, bạn cần xem xét việc đưa người dùng tải trực tiếp lên S3/Vimeo/ở đâu và sau đó kết nối dữ liệu ứng dụng của bạn với các nội dung được tải lên này.

Nếu bạn đang sử dụng Ruby, thì đá quý trực tiếp sóng mang có thể đáng xem xét cách thực hiện. Không có các dịch vụ bên thứ ba ngoài đó cho phép bạn thực hiện điều này thông qua một số mã mà bạn có thể thả vào trang, nhưng chúng đi kèm với chi phí đính kèm.

+0

Cảm ơn Neil, sự cố tôi đã mô tả ở trên dường như không phải là hết thời gian chờ. Không có "H12 - Yêu cầu thời gian chờ" trong nhật ký.Tuy nhiên, tôi hiểu rằng việc định thời gian là một rủi ro lớn với các tệp tải lên lớn, vì vậy tôi sẽ xem xét các video tải lên trực tiếp. Có lẽ điều đó cũng sẽ giải quyết vấn đề ở trên. – stephenalexbrowne

+0

Nên. Tôi đoán bạn đã thử nghiệm trên một kết nối phong nha cho đến nay. –

+0

Chỉ khi nào kết nối không hoạt động trong 30 giây là nó đã hết thời gian chờ. –

2

Tôi nghĩ tùy chọn tốt nhất ở đây thực sự là tải trực tiếp lên S3. Nó rẻ hơn và an toàn hơn nhiều so với việc cho phép người dùng tải tệp lên máy chủ của riêng bạn (hoặc Heroku trong trường hợp này). Nó cũng là một mô hình được chứng minh tốt được sử dụng bởi rất nhiều nền tảng lưu trữ video (tôi biết vzaar làm điều này).

Kiểm tra các jQuery upload plugin, cho phép cập nhật trực tiếp đến S3: https://github.com/blueimp/jQuery-File-Upload

Ngoài ra kiểm tra Railscasts xung quanh chủ đề này: # 381 và # 383.

Các vấn đề liên quan