Dragonflyを使用して、Rails アプリの処理済み画像を提供しています。Dragonfly は、これらの処理された画像への将来のアクセスをRack::Cacheに依存しているため、Dragonfly はこれらの画像を何度も処理する必要がなく、CPU 時間を無駄にします。
私の問題はここから始まります: Rack::Cache 経由でファイルを送信しても Rails プロセスが引き続きビジー状態であることが正しければ、30 枚の画像のページを表示すると、これらの画像のファイル サイズが小さい場合でも、Rails プロセスがかなり拘束されます。早く。さらに数人の訪問者がそのページにアクセスすると、応答時間が非常に遅くなります。これらのファイルを X-Sendfile 経由で提供するにはどうすればよいですか?
で次のように設定しましたがproduction.rb
、これらは Rails のアセット用であり、Dragonfly ファイル用ではないことがわかっています。
config.serve_static_assets = false
config.action_dispatch.x_sendfile_header = "X-Sendfile"
Rack::Cache が何らかの形で X-Sendfile をサポートしていることは知っています (おそらくRack::Sendfileを介して)。これは、に応答する本体を生成するため#to_path
です。ただし、これを有効にする方法がわかりません。Rack::Cache からのファイルをチェックすると、X-Sendfile 情報が表示されません。
Date: Wed, 02 Nov 2011 11:38:28 GMT
Server: Apache/2.2.3 (CentOS)
X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 3.0.9
Content-Disposition: filename="2.JPG"
Cache-Control: public, max-age=31536000
Etag: "3174d486e4df2e78a5ff9174cacbede5787d4660"
X-Content-Digest: c174408eda6e689998a40db0aef4cdd2aedb3b6c
Age: 28315
X-Rack-Cache: fresh
Content-Length: 22377
Status: 200
Content-Type: image/jpeg
私は、ネット上の投稿に基づいて、次のようなものを見ることになっていることを知っています:
X-Sendfile: /path/to/file
最終的に、Dragonfly または Rack::Cache (または両方) を構成する必要があるかどうかはわかりません。Dragonfly や Rack::Cache を取得して X-Sendfile 経由でファイルを提供するにはどうすればよいですか?
私のセットアップに関する情報:
- レール 3.1.1
- 乗客 3.0.9
- CentOS
- 私の知る限り、Sendfileモジュールがインストールされています。私は仮想ホスト構成で指定して
XSendFile On
おりXSendFilePath /path/to/app
、ApacheはディレクティブXSendFile
が存在しないことについて文句を言いません。
ありがとう!
2011 年 11 月 6 日更新
この古い更新に基づいてRack::Sendfile
、 が の前に配置されている限りRack::Cache
、X-Sendfile が使用されます。私はそれをしました、そしてこれは私のミドルウェアがどのように見えるかです. ただし、ファイルにはまだ X-Sendfile タグがありません。繰り返しますが、これが X-Sendfile が有効になっているかどうかを判断する確実な方法かどうかわからないので、Passenger キューを調べました。ページにアクセスすると、キューが大幅に妨げられているようです。
2011 年 11 月 7 日更新
これは純粋に Rack::Cache と Rails 3.1 の問題のようです。Rack::Cache は Rack::Sendfile を介した X-Sendfile の使用をサポートしていますが (上で述べたように、Rack::Cache はDisk EntityStoreを使用する場合、それが返すボディは File のサブクラスであるto_path
ため、 Responds_to を使用するため)、Rails 3.1独自のストレージ ソリューションを使用します。Rails 3.1 は、ファイルで何も指定しない場合、デフォルトで設定されているActiveSupport::Cache::FileStoreを使用します。production.rb
FileStore の問題は、それが返す本文がアップストリームに送信される応答の一部になることです。その本文は に応答しないためto_path
です。本体はActiveSupport::Cache::Entryのインスタンスです。ここで、FileStore がキャッシュされたファイルを読み取るように要求されると、それを読み取ってFile.open('/path/to/file') {|f| Marshal.load(f) }
Entry のインスタンスを返すことがわかります。最終的にアップストリームに渡されてクライアントに戻される値はEntry#valueです。
私の質問
これにパッチを当てるか、Rails に Rack::Cache 独自のディスク ストアを使用させるかを決定するために、いくつか質問があります。
- Rack::Cache 独自のストレージ ソリューションが Rails 3.1 で使用されなかった理由は何ですか? なぜ Rails は独自のものを持っているのですか?
- マーシャルが使用される理由はありますか? 代わりにデータのバイトストリームを送り返す必要がある理由はありますか?
いつもより深く入り込んで、ちゃんと理解できたらビックリ。答えが見つかることを願っています!