在Rails中使用aws-s3 gem的AWS :: S3 :: NoConnectionEstablished错误

时间:2010-09-14 22:27:06

标签: ruby-on-rails amazon-s3 paperclip

尝试使用paperclip + s3下载文件时,我收到了AWS :: S3 :: NoConnectionEstablished异常。我可以启动s3sh并使用我的配置中的s3凭据创建一个连接。我可以采取什么样的最佳步骤来调试此问题?这就是我的模型:

has_attached_file :file,
                    :storage => :s3,
                    :s3_permssions => :private,
                    :path => lambda { |attachment| ":id_partition/:basename.:extension" },
                    :url => lambda { |attachment| "products/:id/:basename.:extension" },
                    :s3_credentials => "#{Rails.root}/config/amazon_s3.yml",
                    :bucket => "products.mycompany.com"

错误发生在这里:

def temporary_s3_url(options={})
    options.reverse_merge! :expires_in => 10.minutes #, :use_ssl => true
    hard_url = AWS::S3::S3Object.url_for file.path, file.options[:bucket], options
    # Use our vanity URL
 hard_url.gsub("http://s3.amazonaws.com/products.mycompany.com","http://products.mycompany.com")
  end

我尝试将连接编码为temporary_s3_url方法中的第一行,但我收到“未找到存储桶”错误。我认为问题肯定是回形针在初始化我的s3配置时遇到了问题。

2 个答案:

答案 0 :(得分:0)

我在两个应用程序上都有S3和Heroku的回形针。这对我有用:

在您的模式中:

has_attached_file :image, 
   :styles => {  :thumb => "250x250>" },
   :storage => :s3, :s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
   :path => "username/:attachment/:style/:id.:extension"

在config / s3.yml

development:
  bucket: name
  access_key_id: xyz
  secret_access_key: xyz

test:
  bucket: name
  access_key_id: xyz
  secret_access_key: xyz

production:
  bucket: name
  access_key_id: xyz
  secret_access_key: xyz

当然在你的环境中。你需要包含宝石,或者你包含宝石。

答案 1 :(得分:0)

请记住,存储到S3是不可靠的 - 连接可能会丢失,商店在完成之前会失败等等。

我创建了自己的库例程,尝试进行存储,但会捕获各种错误。对于无连接错误,我重新连接。对于其他存储错误,我重试(最多三次)。您可能还希望在重试之间等待一秒钟。

<强>加

以下是我用于AWS呼叫的库例程。

您需要添加/修改救援条款以捕获您遇到的错误。您的connection_reset和错误报告方法也将特定于您的sw。

# Usage example:
# aws_repeat("Storing #{bucket}/#{obj}"){
#   AWS::S3::S3Object.store(obj, data, bucket, opt)}    

def aws_repeat(description = nil)
  # Calls the block up to 3 times, allowing for AWS connection reset problems
  for i in 1..3
    begin
      yield
    rescue Errno::ECONNRESET => e
      ok = false
      ActiveRecord::Base.logger.error \
           "AWS::S3 *** Errno::ECONNRESET => sleeping"
      sleep(1)
      if i == 1
        # reset connection
        connect_to_aws # re-login in to AWS
        ActiveRecord::Base.logger.error \
           "AWS::S3 *** Errno::ECONNRESET => reset connection"
      end        
    else
      ok = true
      break
    end
  end

  unless ok
    msg = "AWS::S3 *** FAILURE #{description.to_s}"
    ActiveRecord::Base.logger.error msg
    security_log(msg)
  end

  ok
end

############################################
############################################

def connect_to_aws
  # load params. Cache at class (app) level 
  @@s3_config_path ||= RAILS_ROOT + '/config/amazon_s3.yml'
  @@s3_config ||= 
       YAML.load_file(@@s3_config_path)[ENV['RAILS_ENV']].symbolize_keys

  AWS::S3::Base.establish_connection!(
    :access_key_id     => @@s3_config[:access_key_id],
    :secret_access_key => @@s3_config[:secret_access_key],
    :server            => @@s3_config[:server],
    :port              => @@s3_config[:port],
    :use_ssl           => @@s3_config[:use_ssl],
    :persistent        => false # from http://www.ruby-forum.com/topic/110842
    )

  true 
end