Подтвердить что ты не робот

Используйте CDN с несущей волной + туман в s3 + cloudfront с рельсами 3.1

Я использую туман с carrierwave на моем веб-сайте. Но изображения загружаются очень медленно.

Затем я хочу ускорить загрузку изображений с 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 в файл fog в несущей с s3 и облачным?

4b9b3361

Ответ 1

Похоже, вы не добавили строку ниже в свою конфигурацию. Вам нужно будет заменить адрес образца ниже адресом облачного интерфейса от Amazon.

Из github README: https://github.com/jnicklas/carrierwave

"Вы можете дополнительно указать имя хоста CDN в конфигурации. Это настоятельно рекомендуется, так как без него каждый запрос требует поиска этой информации"

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

Ответ 2

CarrierWave не будет работать, если вы установите config.fog_public = false и укажите config.asset_host в дистрибутив CloudFront. Это было зарегистрировано несколько раз:

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

В недавнем проекте я был счастлив использовать CarrierWave для обработки загрузок на S3, но хотел, чтобы он возвращал подписанный URL CloudFront при использовании Model.attribute_url. Я придумал следующее (по общему признанию, уродливое) обходное решение, которое, надеюсь, другие могут извлечь выгоду или улучшить:

Добавьте 'cloudfront-signer в свой проект и настройте его в соответствии с инструкциями. Затем добавьте следующее переопределение /lib/carrierwave/uploader/url.rb в новый файл в config/initializers (обратите внимание на несколько вложений 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

Наконец, в config/initializers/carrierwave.rb:

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

config.fog_public = false

Что это. Теперь вы можете использовать Model.attribute_url, и он вернет подписанный URL CloudFront в приватный файл, загруженный CarrierWave в ваш ведро S3.

Ответ 3

кажется, что amazon cdn не работает с config.fog_public = false, поэтому частные файлы доступны только из s3, а не из cdn

Ответ 4

После некоторого поиска и борьбы с этим в течение долгого времени я нашел страницу, в которой говорится, что CarrierWave не поддерживает подписанные URL-адреса CloudFront. Подписанные URL-адреса CloudFront отличаются от подписанных URL-адресов S3, что вызвало у меня некоторую путаницу. Как только я понял это, было намного легче узнать, что делать.

Если вы настроите CarrierWave с помощью config.fog_public = false, то он автоматически начнет подписывать S3-URL, но он не может быть настроен для работы с Fog и облачным контентом CloudFront в версии CarrierWave. Я использую (1.0.0). Я даже попытался использовать драгоценный камень 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, я бы это получил (с двойными косыми чертами перед "uploads" ):

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

Это тоже показало, что CarrierWave еще не был разработан для использования с CloudFront. Надеюсь, они улучшат его. Это была моя работа. Это уродливо, но он работал, чтобы сделать то, что мне было нужно, без необходимости модифицировать CarrierWave, так как я надеюсь, что CarrierWave в какой-то момент добавит поддержку CloudFront.

  • Сначала я выполнил поиск/замену регулярного выражения на моем URL-адресе и удалил часть узла S3 и добавьте часть хоста CloudFront. cf_url = s3_url.gsub("my_bucket_name.s3-us-west-2.amazonaws.com", "s3.cloudfront_domain_name.com")
  • Далее я снова нашел/заменил регулярное выражение для удаления подписанного URL S3 в конце строки: non_signed_cf_url = cf_url.gsub(/\?.+/, '') Это потому, что подпись будет неправильной, потому что она использовала API для S3, а не для CloudFront для подписания URL-адреса.
  • Теперь я снова переписываю URL, используя cloudfront-signer gem: signed_cf_url = Aws::CF::Signer.sign_url(non_signed_cf_url, :expires => 1.day.from_now)

Есть несколько других вещей, о которых вам нужно знать при обслуживании личного контента на CloudFront:

  • В настройках поведения кэша для вашего шаблона пути (не обязательно по умолчанию) установите: "Ограничить доступ к просмотру (Использовать подписанные URL-адреса или Подпись Cookies) "на" Да "
  • Установите "доверенные подписчики" на "self"
  • Установите "Переадресация и кеширование строки запроса" на "Переслать все, кеш на основе всех", если вы хотите использовать другие строки запроса больше, чем подпись CloudFront в вашем URL-адресе, например response-content-disposition и response-content-type (я был чтобы заставить их работать успешно, но они должны быть правильно закодированы url_encoded.)
  • В настройках источника CloudFront укажите свой идентификатор доступа и установите "Разрешения на получение прав на ведро" на "Да, обновить политику ведра".
  • В ваших общих настройках распространения убедитесь, что "Состояние распространения" "Включено", и что вы добавили CNAME в "Альтернативные имена доменов" (CNAME) ", если вы используете его.
  • Если вы используете CNAME, убедитесь, что ваш DNS правильно настроен, чтобы указать его на ваше имя распространения CloudFront.
  • Наконец, после того, как вы установили конфигурации, существует долгое ожидание, пока AWS обновляет дистрибутив, поэтому вы не увидите, что ваши изменения произойдут сразу. Может показаться, что ваше приложение/веб-сайт все еще сломан, пока изменения не распространяются через CloudFront. Это может затруднить настройку, потому что, если вы ошибаетесь, вам придется долго ждать, прежде чем вы сможете увидеть, как ваши изменения вступают в силу, и вы не можете быть уверены, что произошло. Но с этими настройками я смог заставить его работать для меня.
  • Вы также можете создать более одного шаблона пути кэширования, чтобы некоторый контент был приватным и для него требовался подписанный URL CloudFront, а другой контент - нет. Например, я устанавливаю шаблон пути *.mp4, который требует подписи для всех файлов mp4 и помещает его выше по умолчанию. И тогда у меня установлен режим кэширования по умолчанию, для которого НЕ требуется подписанные URL-адреса, что позволяет публиковать все другие файлы, такие как изображения, через дистрибутив CloudFront.