2012-03-31 78 views
17

我使用fogcarrierwave在我的網站上。但圖像加載非常緩慢。在s3 + cloudfront中使用帶有carrierwave + fog的CDN與導軌3.1

然後我想加快用CDN加載圖像。

我按照這個教程創建CDN的圖像:

http://maketecheasier.com/configure-amazon-s3-as-a-content-delivery-network/2011/06/25

我現在我的分佈部署的圖像,但我不知道如何正常工作的CDN。我在初始化/ fog.rb下面的配置:

CarrierWave.configure do |config| 
    config.fog_credentials = { 
    :provider    => 'AWS', 
    :aws_access_key_id  => 'key', 
    :aws_secret_access_key => 'key', 
    :region     => 'eu-west-1' 
    } 
    config.fog_host = "http://da33ii2cvf53u.cloudfront.net" #config.asset_host instead of config.fog_host for new fog gem versions 
    config.fog_directory = 'pin-pro' 
    config.fog_public  = false 
    #config.fog_attributes = {'Cache-Control' => 'max-age=315576000'} 
end 

我不知道這是正確的,但在我的本地機器它不爲我工作得很好。我看到的圖像位置,是同一條路線爲前:

https://s3-eu-west-1.amazonaws.com/pin-pro/uploads/pins/medium_610cafbe-5d43-4223-ab0e-daa4990863c4.jpg?AWSAccessKeyId=AKIAIDX34WHYKB3ZKFVA&Signature=RwQriNpiRXaTxyfYVvYjsvclUa8%3D&Expires=1333203059 

我如何添加一個CDN霧在carrierwave文件,S3和CloudFront的?

+0

如果我使用該設置:'fog_host',那麼我得到這個錯誤:CarrierWave :: Uploader :: Base:Class的undefined方法'fog_host ='什麼版本的carrierwave是人們使用的? – 2013-07-29 15:57:19

+0

您應該使用'config.asset_host'而不是'config.fog_host'。我已經將此問題添加到了問題中。祝你好運! – hyperrjas 2013-07-29 17:21:31

+0

是的,我注意到,經過一些挖掘:)謝謝。 – 2013-08-11 13:42:38

回答

7

它看起來像你沒有添加下面的行到你的配置。您需要將以下示例地址替換爲Amazon的雲端地址。

從GitHub的自述:https://github.com/jnicklas/carrierwave

「您可以選擇包括在配置您的CDN主機名,這是強烈推薦,因爲沒有它的每個請求都需要此信息的查詢。」

config.asset_host = "http://c000000.cdn.rackspacecloud.com"

+0

這不適用於CloudFront私人內容。 – Allen 2016-12-27 09:43:18

6

看來,亞馬遜的CDN不config.fog_public = false工作,所以私人文件只是從S3訪問,而不是從CDN

10

CarrierWave不會活像k當您將config.fog_public = false指向config.asset_host到CloudFront分配。這已被證明多次:

https://github.com/carrierwaveuploader/carrierwave/issues/1158 https://github.com/carrierwaveuploader/carrierwave/issues/1215

在最近的一個項目,我很高興通過CarrierWave處理上傳到S3,但希望它使用Model.attribute_url當返回一個簽名的CloudFront的URL。我想出了以下(肯定是醜陋的)解決方法,我希望其他人可以從中受益或提高:

'cloudfront-signer' gem添加到您的項目並根據說明進行配置。然後加入/lib/carrierwave/uploader/url.rb的以下重寫一個新的文件中配置/初始化(注意:AWS :: CF的多次插入:: Signer.sign_url):

module CarrierWave 
     module Uploader 
     module Url 
      extend ActiveSupport::Concern 
      include CarrierWave::Uploader::Configuration 
      include CarrierWave::Utilities::Uri 

      ## 
      # === Parameters 
      # 
      # [Hash] optional, the query params (only AWS) 
      # 
      # === Returns 
      # 
      # [String] the location where this file is accessible via a url 
      # 
      def url(options = {}) 
      if file.respond_to?(:url) and not file.url.blank? 
       file.method(:url).arity == 0 ? AWS::CF::Signer.sign_url(file.url) : AWS::CF::Signer.sign_url(file.url(options)) 
      elsif file.respond_to?(:path) 
       path = encode_path(file.path.gsub(File.expand_path(root), '')) 

       if host = asset_host 
       if host.respond_to? :call 
        AWS::CF::Signer.sign_url("#{host.call(file)}#{path}") 
       else 
        AWS::CF::Signer.sign_url("#{host}#{path}") 
       end 
       else 
       AWS::CF::Signer.sign_url((base_path || "") + path) 
       end 
      end 
      end 

     end # Url 
    end # Uploader 
end # CarrierWave 

然後覆蓋/lib/carrierwave/storage/fog。RB通過添加以下到同一個文件的底部:

require "fog" 

module CarrierWave 
    module Storage 
    class Fog < Abstract 
     class File 
      include CarrierWave::Utilities::Uri 
      def url 
      # Delete 'if statement' related to fog_public 
      public_url 
      end 
     end 
    end 
    end 
end 

最後,在配置/初始化/ carrierwave.rb

config.asset_host = " http://d12345678.cloudfront.net "

config.fog_public = false

就是這樣。您現在可以使用Model.attribute_url,它會將已簽名的CloudFront URL返回到由CarrierWave上傳到您的S3存儲桶的私有文件。

1

經過一段時間的搜索和苦苦掙扎之後,我發現一個網頁說CarrierWave不支持CloudFront簽名的網址。 CloudFront簽署的網址與S3簽名的網址不同,這使我產生了一些混淆。一旦我明白了這一點,知道該怎麼做才容易多了。

如果用config.fog_public = false配置CarrierWave那麼它就會自動開始申請S3的網址,但它不能被配置爲Fog和CarrierWave的版本我使用(1.0.0) CloudFront的私人內容合作。我甚至嘗試使用carrierwave-aws寶石,這也沒有幫助。

那麼會發生什麼是CarrierWave將簽署的URL,主機會是這個樣子:

https://my_bucket_name.s3-us-west-2.amazonaws.com/uploads/...?signature... 

直接指向S3鬥,但我需要它指向CloudFront的。我需要主機看起來像這樣:

https://s3.cloudfront_domain_name.com/uploads/... 

如果我設置config.asset_host等於我的CloudFront的位置是我(之前「上傳」雙斜槓)得到這個,會發生什麼:

https://s3.cloudfront_domain_name.com//uploads/... 

這也明確表示CarrierWave尚未設計用於CloudFront。希望他們會改進它。這是我的解決方法。這很醜陋,但它能夠完成我所需要的功能,而無需修改CarrierWave本身,因爲我希望CarrierWave在某些時候會添加對CloudFront的支持。

  1. 首先,我做了一個正則表達式查找/在我的網址替換和刪除S3主機部分 並把我的CloudFront的主機部分。 cf_url = s3_url.gsub("my_bucket_name.s3-us-west-2.amazonaws.com", "s3.cloudfront_domain_name.com")
  2. 接下來,我做了另外一個正則表達式查找/替換 去除S3在字符串的結尾簽署網址: non_signed_cf_url = cf_url.gsub(/\?.+/, '')這是因爲,因爲它是使用S3的API,而不是爲CloudFront的的簽名將是不正確的簽署網址。
  3. 現在我重新登錄的網址嘍,使用cloudfront-signer寶石: signed_cf_url = Aws::CF::Signer.sign_url(non_signed_cf_url, :expires => 1.day.from_now)

有你需要知道的CloudFront的服務私人內容時的一些其他的東西:

  • 在路徑模式的緩存行爲設置中(不一定是默認值),請將「限制查看器訪問 (使用簽名的URL或 簽名的Cookie)」設置爲「是」
  • 將「Trusted簽名者「改爲」自己「
  • 如果您想要在URL中使用比CloudFront簽名更多的其他查詢字符串,例如response-content-dispositionresponse-content-type(其中包含一個或多個字符),請將」查詢字符串轉發和緩存「我能得到這些成功運行,但它們必須正確url_encoded。)
  • 在您的CloudFront的起源設置,設置您的訪問身份,並設置「關於鬥授予讀取權限」爲「Yes,更新桶政策」
  • 在您的常規分配設置中,確保「分配狀態」爲「已啓用」,並且您已將CNAME添加到「替代域名 (CNAME)」(如果您使用的是)。
  • 如果使用CNAME,請確保您的DNS已正確配置爲將其指向您的CloudFront分配的名稱。
  • 最後,一旦設置了配置,AWS會更新分配,因此您不會立即看到您的更改。在更改通過CloudFront傳播之前,您的應用/網站似乎仍然存在問題。這可以使配置變得困難,因爲如果你弄錯了,你必須等很長時間才能看到你的改變生效,你可能不知道發生了什麼。但是通過這些設置,我能夠爲我工作。
  • 您也可以創建多個緩存路徑模式,以便某些內容是專用的,並且需要CloudFront簽名的url,而其他內容則不是。例如,我設置了一個路徑模式*.mp4,它需要所有mp4文件的簽名並將其放在默認行爲之上。然後,我將默認緩存行爲設置爲不需要簽名的網址,這可以通過CloudFront分配公開訪問所有其他文件(如圖像)。
相關問題