8

我正在使用托管在 Heroku 上的Dragonfly机架/缓存的组合。

我正在使用 Dragonfly 上传资产。缩略图被即时处理并存储在 rack/cache 中,以便从 memcached 快速交付(通过Memcachier 插件)。

常规静态资产也通过 rack/cache 缓存在 memcached 中。

我的问题是任何超过 1MB 的上传文件都会在我的应用程序中导致 500 错误。

2013-07-15T10:38:27.040992+00:00 app[web.1]: DalliError: Value too large, memcached can only store 1048576 bytes per key [key: d49c36d5db74ef45e957cf169a0b27b83b9e84de, size: 1502314]
2013-07-15T10:38:27.052255+00:00 app[web.1]: cache: [GET /media/BAhbBlsHOgZmSSIdNTA3Njk3ZWFiODBmNDEwMDEzMDAzNjA4BjoGRVQ/WTW_A5Flyer_HealthcareMedicalObsGynae_WEB.pdf] miss, store
2013-07-15T10:38:27.060583+00:00 app[web.1]: !! Unexpected error while processing request: undefined method `each' for nil:NilClass

Memcache 有 1MB 的限制,所以我可以理解为什么我的资产没有被缓存,但我宁愿它不会破坏服务资产。

我什至不确定这个错误来自哪里。大概来自其他机架中间件之一?

增加最大文件大小似乎没有任何影响。

config.cache_store = :dalli_store, ENV["MEMCACHIER_SERVERS"].split(","), {¬
  :username        => ENV["MEMCACHIER_USERNAME"],¬
  :password        => ENV["MEMCACHIER_PASSWORD"],¬
  :value_max_bytes => 5242880 # 5MB¬
}

从长远来看,我知道将这种资产从 Heroku 中移出是明智之举,但这不会是一项快速的工作。

在此期间,我可以做些什么来在 Heroku 上提供这些资产而不会出现错误?

4

3 回答 3

9

因此,与@jordelver 的问题相反,我发现设置:value_max_bytesdalli 的选项确实有效。我正在以稍微不同的方式设置 Rack::Cache,这可能会有所不同。

这是我production.rb配置 Rack::Cache 的内容:

client = Dalli::Client.new(ENV["MEMCACHIER_SERVERS"],
                           :username => ENV["MEMCACHIER_USERNAME"],
                           :password => ENV["MEMCACHIER_PASSWORD"],
                           :value_max_bytes => 10485760)
config.action_dispatch.rack_cache = {
  :metastore    => client,
  :entitystore  => client
}
config.static_cache_control = "public, max-age=2592000"

使用上述方法,超过 1MB 的值将在日志中打印一些错误,但它们不会导致客户端出现 5xx 错误,只是缓存未命中。

PS 我为 MemCachier 工作 :) 所以我们有兴趣尝试解决这个问题。请让我知道它是否有效。

于 2013-09-17T22:26:38.257 回答
8

我遇到了与@jordelver 相同的问题,并设法通过猴子补丁解决了 memcachier 的限制Dragonfly::Response

module Dragonfly
  class Response
    private
    def cache_headers
      if job.size > 1048576
        {
          "Cache-Control" => "no-cache, no-store",
          "Pragma" => "no-cache"
        }
      else
        {
           "Cache-Control" => "public, max-age=31536000", # (1 year)
           "ETag" => %("#{job.signature}")
        }
      end
    end
  end
end

本质上,如果大小超过 1048576 字节,则发送无缓存标头。

于 2013-10-08T15:59:05.333 回答
0

application.js的太大了,rack-cache所以我做了:

# in config/environments/development.rb
config.action_dispatch.rack_cache = {
  metastore: 'file:/var/cache/rack/meta',
  entitystore: 'file:tmp/cache/rack/body'
}

它有效!

将元数据存储在内存缓存中,但将实际文件存储在文件系统中而不是内存中。

于 2014-09-12T17:47:07.257 回答