2

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 独自のディスク ストアを使用させるかを決定するために、いくつか質問があります。

  1. Rack::Cache 独自のストレージ ソリューションが Rails 3.1 で使用されなかった理由は何ですか? なぜ Rails は独自のものを持っているのですか?
  2. マーシャルが使用される理由はありますか? 代わりにデータのバイトストリームを送り返す必要がある理由はありますか?

いつもより深く入り込んで、ちゃんと理解できたらビックリ。答えが見つかることを願っています!

4

2 に答える 2

1

ApacheとPassengerではなくnginxとunicornを使用していましたが、これを機能させることになりました。

Github の問題で指摘したように、 Rack::Cache を切り替えて、rails:/ ストアではなく標準の file:/ ストアを使用するように戻すことができます。これにより、応答が に応答できるようになりto_pathます。

config.action_dispatch.rack_cache = {
  :verbose     => true,
  :metastore   => URI.encode("file:/PATH/TO/CACHE/STORE"),
  :entitystore => URI.encode("file:/PATH/TO/CACHE/STORE")
}

Dragonfly はこれを開発段階で行いますが、必要に応じて本番環境でも行うことができます。これを行う際の注意点は、Rack::Cache を使用する Rails キャッシュ機能のいずれかを使用する場合、キャッシュ エントリは標準の Rails ストアではなくそのストアに保存されるため、必要な場合はそのことを考慮する必要があります。これらのエントリを手動でクリアします。

config.action_dispatch.x_sendfile_header 引数を使用して、Rack::Sendfile ミドルウェアをスタックの先頭に挿入することも確認する必要があります。config 引数がないと、Rack::Sendfile はヘッダーを追加しません。

config.middleware.insert 0, Rack::Sendfile, config.action_dispatch.x_sendfile_header

My Gistには、production.rb と nginx テンプレートの関連する行が表示されます。Apache X-Sendfile モジュールで動作するように簡単に適合させる必要があります。

これをテストする場合に注意すべきもう 1 つの点は、たとえば cURL を介して HEAD リクエストのみを送信すると、Rack::Cache が実際に本文を送信しないため、応答で関連する X-Sendfile ヘッダーを取得できないことです。 HEAD リクエストなので、Rack::Sendfile には呼び出すものがありませんto_path

于 2012-09-16T05:43:12.080 に答える
1

Varnish の代わりに、Apache の mod_disk_cache を使用できます。既に Apache を実行しているため、設定する作業は少なくなります。

于 2011-12-19T15:33:11.673 に答える