我使用
CarrierWave(0.9.0),Fog(1.14.0)和S3来存储用户头像.确定给定用户的头像URL似乎需要很长时间.随后的通话时间大大缩短.
配置/初始化/ fog.rb
CarrierWave.configure do |config| config.fog_credentials = { provider: 'AWS',aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'] } config.fog_directory = ENV['AWS_S3_BUCKET_AVATAR'] config.fog_public = false end
user.rb
mount_uploader :avatar,ImageUploader
安慰
irb(main):002:0> Benchmark.measure { user.avatar_url } => 0.500000 0.020000 0.520000 ( 0.537884) irb(main):003:0> Benchmark.measure { user.avatar_url } => 0.000000 0.000000 0.000000 ( 0.001830) irb(main):004:0> Benchmark.measure { user.avatar_url } => 0.000000 0.000000 0.000000 ( 0.001454) irb(main):005:0> Benchmark.measure { user.avatar_url } => 0.000000 0.000000 0.000000 ( 0.000998)
New Relic报告有时user.avatar_url需要1秒钟.什么可能导致这么慢? There’s a discussion on slow URL generation for public files,但我的头像不公开.
更新1:
在第一次调用之前明确要求Fog和CarrierWave没有区别,因为返回false,表明它们已经被加载.
irb(main):002:0> require 'carrierwave' => false irb(main):003:0> require 'fog' => false irb(main):004:0> Benchmark.measure { user.avatar_url } => 0.510000 0.030000 0.540000 ( 1.627774)
更新2:
这是上传者:
# encoding: utf-8 class ImageUploader < CarrierWave::Uploader::Base include CarrierWave::RMagick storage :fog def store_dir "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" end version :s_32 do process resize_to_fill: [32,32] end version :s_40 do process resize_to_fill: [40,40] end version :s_50 do process resize_to_fill: [50,50] end version :s_115_120 do process resize_to_fill: [115,120] end version :s_128 do process resize_to_fill: [128,128] end def extension_white_list %w(jpg jpeg gif png) end end
更新3:
user.avatar.url似乎没有什么区别:
irb(main):003:0> Benchmark.measure { user.avatar.url } => 0.500000 0.030000 0.530000 ( 0.926975)
解决方法
我认为雾的需要可能仍然存在问题(尽管现在不太明显).由于雾中有很多不同的东西,我们很久以前就做出了选择,推迟加载许多依赖项,直到它们被需要为止.这有利于加速“迷雾”,但在第一次发生某些事情时可能会减慢速度.不知道我是怎么忘记这个部分的,但是在我的机器上进行一些小的基准测试时,考虑到这一点,我当然可以看到减速.
要解决这个问题,您可以将上面的相关需求基准更改为:
require 'benchmark' require 'fog' Fog::Storage.new( provider: 'AWS',aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'] ) Benchmark.measure { ... }
您可能看起来有些奇怪,因为您没有使用该连接,但我将其设置为推迟加载S3细节,直到您这样做(例如,您不必加载S3细节以便使用EC2).但是,通过在某个较早的时间初始化连接,可以避免这种开销.希望这至少可以让你更接近你想要的地方.