8

Heroku でホストされているDragonflyラック/キャッシュの組み合わせを使用しています。

アップロードされたアセットに Dragonfly を使用しています。サムネイルはオンザフライで処理され、memcached から ( Memcachier アドオンを介して) 高速に配信されるようにラック/キャッシュに保存されます。

通常の静的アセットも、ラック/キャッシュ経由で 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 には 1 MB の制限があるため、アセットがキャッシュされなかった理由は理解できますが、アセットの提供が中断されないようにしたいと考えています。

このエラーがどこから来ているのかさえわかりません。おそらく他のラックミドルウェアの1つからですか?

最大ファイル サイズを大きくしても、影響はないようです。

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_bytes、dalliのオプションを設定すると機能することがわかりました。Rack::Cache を少し異なる方法でセットアップしているため、違いが生じる可能性があります。

これは、production.rbRack::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 バイトを超える場合は、no-cache ヘッダーを送信します。

于 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'
}

そしてそれはうまくいきます!

メタデータは memcache に保存しますが、実際のファイルはメモリではなくファイル システムに保存します。

于 2014-09-12T17:47:07.257 に答える