2010-01-29 104 views
4

我使用回形針在S3中上傳圖像。 但我注意到,這種上傳速度很慢。我認爲,因爲在完成提交之前,文件必須經過我的服務器,經過處理併發送到S3服務器。使用回形針加速S3上傳

有沒有加速這個的方法?

感謝

回答

0

使用延遲的工作,這是一個很好的例子here
或者您可以使用閃光燈的上傳。

1

你想改善上傳的外觀是快或實際上使上傳速度更快?

如果是前者,可以使用delayed_job之類的東西將圖像處理邏輯放入後臺任務中。這樣,當用戶點擊按鈕時,他們會在處理圖像時立即轉到下一頁(可以顯示「處理中」圖像佔位符,直到任務完成)。

如果是後者,則完全取決於您的服務器和Internet連接。你在哪裏舉辦?

0

由於cwninja建議,我們直接上傳到S3,以擺脫這種額外的上傳。我們利用這個博客帖子描述的插件的修改版本:

http://elctech.wpengine.com/2009/02/updates-on-rails-s3-flash-upload-plugin/

我們被修改爲處理多個文件上傳(改寫了柔性物體

不知道如何好這個玩弄回形針,我們使用attachment_fu,但它不是那麼糟糕讓它與合作。

+0

鏈接中斷 – Tony 2010-06-14 17:21:13

+0

新鏈接在這裏:http://web.elctech.com/2009/02/26/updates-on-rails-s3-flash-upload-plugin/ – 2010-06-29 20:38:38

+0

我只是修復了斷開的鏈接。 – 2012-07-28 21:08:34

0

如果你最終會從您的Rails服務器卸載工作直接上傳到S3的路線,請查看我的樣本項目:

示例項目使用Rails 3,Flash和基於MooTools的-FancyUploader上傳直接到S3:https://github.com/iwasrobbed/Rails3-S3-Uploader-FancyUploader

使用Rails 3 Sample項目,閃存/ Silverlight的/ GoogleGears /的BrowserPlus和基於jQuery的Plupload直接上傳到S3:https://github.com/iwasrobbed/Rails3-S3-Uploader-Plupload

順便說一句,你可以做後期處理回形針使用這樣的博客文章描述:

http://www.railstoolkit.com/posts/fancyupload-amazon-s3-uploader-with-paperclip

1

你沒有張貼任何代碼,所以我要做出一些假設在這裏:

    在你的項目
  • 你有一個AlbumImage模型
  • Album has_many :images
  • 您已有 paperclipaws-sdk 正確設置提着水桶和一切
  • 要一次

上傳許多圖像爲了上傳多個圖片,表單會是這個樣子:

<%= form_for @album, html: { multipart: true } do |f| %> 
    <%= f.file_field :files, accept: 'image/png,image/jpeg,image/gif', multiple: true %> 

    <%= f.submit %> 
<% end %> 

你的控制器將使用一張專輯是這個樣子

class AlbumsController < ApplicationController 
    def update 
    @album = Album.find params[:id] 
    @album.update album_params 
    redirect_to @album, notice: 'Images saved' 
    end 

    def album_params 
    params.require(:album).permit files: [] 
    end 
end 

爲了處理圖像,你需要

class Album < ApplicationRecord 
    has_many :images, dependent: :destroy 

    accepts_nested_attributes_for :images, allow_destroy: true 

    def files=(array = []) 
    array.each do |f| 
     images.create file: f 
    end 
    end 
end 

Image文件看起來像這樣

class Image < ApplicationRecord 
    belongs_to :album 

    has_attached_file :file, styles: { thumbnail: '500x500#' }, default_url: '/default.jpg' 

    validates_attachment_content_type :file, content_type: /\Aimage\/.*\Z/ 
end 

這僅僅是一個很重要的東西。通過此設置,上傳總共12張圖像的22張圖像需要在本地服務器上平均執行:files=方法41.1806895秒。要檢查運行方法需要多長時間,請使用:

def files=(array = []) 
    start = Time.now 

    array.each do |f| 
    images.create file: f 
    end 

    p "ELAPSED TIME: #{Time.now - start}" 
end 

您要求更快地上傳許多圖像。有幾種方法可以做到這一點。使用 jobs 將不起作用,因爲您無法將複雜數據(如圖像)傳遞給作業。


改爲使用delayed_paperclip。它將圖像樣式創建(如thumbnail: '500x500#')移動到後臺作業中。

的Gemfile

source 'https://rubygems.org' 

ruby '2.3.0' 

... 
gem 'delayed_paperclip' 
... 

圖像文件

class Image < ApplicationRecord 
    ... 
    process_in_background :file 
end 

它加快了:files=方法。與此前相同的上傳(22張圖像,12MB)使用此設置在我的機器上花費了23.13998秒。這比以前快了1.77963倍。


另一種加快速度的方法是使用Threads。從Gemfile和process_in_background :file行刪除delayed_paperclip。更新您的:files=方法:

def files=(array = [])  
    threads = [] 

    array.each do |f| 
    threads << Thread.new do 
     images.create file: f 
    end 
    end 

    threads.each(&:join) 
end 

你可以試試這個,但得到一些奇怪的錯誤,只看到4個圖像保存。您還必須使用Mutex。此外,您不能在線程上使用:join,因爲如果您加入,該方法將等待線程完成運行。

def files=(array = []) 
    semaphore = Mutex.new 

    array.each do |f| 
    Thread.new do 
     semaphore.synchronize do 
     images.create file: f 
     end 
    end 
    end 
end 

利用這種簡單的改變的方法和無添加的寶石,相同的上傳如0.017628秒運行之前。那就是1,313倍於delayed_paperclip。它也是2,336倍於常規設置。


如果使用delayed_paperclipThreads會發生什麼?

不要更改:files=方法。只需在您的Gemfile中重新打開delayed_paperclip並添加process_in_background :file行。

在我的機器上安裝了此設置後,該方法的平均運行時間爲0.001277秒。這是更快

  • 13.8倍的速度比Threads
  • 18,120.6delayed_paperclip
  • 32,248.0倍的速度比普通安裝

記住,這是我的機器和我尚未在生產中對此進行測試。我也在wifi上,而不是以太網。所有這些都可以改變結果,但我認爲這些數據可以說明一切。

上傳圖像更快。完成。


UPDATE:不要使用delayed_paperclip。它可能會導致繁忙的數據庫,並且某些圖像可能無法保存。我測試過了。我認爲使用線程足夠快。從Image文件中刪除process_in_background行。此外,這裏就是我的files=方法是這樣的:

def files=(array = []) 
    Thread.new do 
    begin 
     array.each { |f| images.create file: f } 
    ensure 
     ActiveRecord::Base.connection_pool.release_connection 
    end 
    end 
end 

注:因爲我們推圖像保存到後臺任務,然後重定向。加載的頁面還沒有圖像。用戶必須 refresh 更新頁面。一種解決方法是使用 polling。 輪詢是當JavaScript每5秒檢查一次更改並對頁面進行更改(如果有)。

另一種選擇是使用 Web Sockets。 既然我們有Rails 5,我們可以使用ActionCable。每次創建圖像時,我們都會播放專輯的更新。如果用戶在該專輯的該頁面上,他們會在數據庫發生更新時立即看到更新,而無需刷新用戶或瀏覽器在無限循環中每隔5秒發出一次請求。

很酷的東西。