プリコンパイルされたアセットをnginxで直接提供することは可能ですか? Railsを使用してアセットを動的に提供することは、20倍遅い(仮想ボックスでは4000リクエスト/秒vs 200リクエスト/秒)のようです)。
それはnginx.confのいくつかの書き換えルールで実行できると思います。ただし、問題は、これらのファイル名にコンテンツのmd5ハッシュが含まれていることです。そのため、これで何ができるかわかりません。
それが不可能な場合、Rails 3.1アセットパイプラインを使用しても全体像がわかりません。クライアントの帯域幅とページのロード時間をx20サーバーの負荷を犠牲にして減らしますか?
何か案は?
UPD:したがって、私はnginxをセットアップし、Railsある方法で、アプリケーションのeverythingが〜3500-4000リクエスト/秒の速度で提供される場合) 。
まず、2つの仮想ホストを追加しました。1つは別のキャッシングプロキシとして機能し、アセットが必要な速度(4k)で提供されることを発見しました。次に、Railsアプリケーションをmemcachedに接続しました(これまで特別なことは何もありません。application.rbの1行だけです:ActionController::Base.cache_store = :mem_cache_store, "localhost"
)
次に、コントローラにexpires_in 1.hour, :public => true if !signed_in?;
のようなものを追加して、デフォルトのキャッシュポリシーをRailsコンテンツに変更し、動的ページの毎秒500リクエストあたりの速度を向上させました(それが何かになる前に) 200に近く、私がこれをすべて始める前に、それは〜50でした)。
さて、私のnginx設定ファイルは次のようになります:
nginx.conf:
...
proxy_cache_path /tmp/blog keys_zone=one:8m max_size=1000m inactive=600m;
proxy_temp_path /tmp;
gzip off;
include /opt/nginx/conf/sites-enabled/*;
サイト対応/ブログ:
server {
listen 8080;
server_name blindsight;
root /home/mike/Rails/blog/public;
Rails_env production;
# serve static content directly
location ~* \.(ico|jpg|gif|png|swf|html)$ {
if (-f $request_filename) {
expires max;
break;
}
}
passenger_enabled on;
location ~ /\.ht {
deny all;
}
}
サイト対応/メイン:
server {
listen 80;
server_name blindsight;
location /authorize
{
proxy_pass_header Cookie;
proxy_pass_header Set-Cookie;
proxy_pass http://127.0.0.1:8080;
}
location /admin
{
proxy_pass_header Set-Cookie;
proxy_pass_header Cookie;
proxy_pass http://127.0.0.1:8080;
}
location / {
root /home/mike/Rails/blog/public;
# All POST requests go directly
if ($request_method = POST) {
proxy_pass http://127.0.0.1:8080;
break;
}
proxy_redirect off;
proxy_pass_header Cookie;
proxy_ignore_headers Set-Cookie;
proxy_hide_header Set-Cookie;
proxy_set_header Host $Host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache one;
proxy_cache_key blog$request_uri;
proxy_cache_valid 200 302 5s;
proxy_cache_valid 404 1m;
proxy_pass http://127.0.0.1:8080;
}
すべては血まみれの稲妻のように高速です:)ありがとうございます。
Railsでの作業の経験はありませんが、私の推測では、proxy_passディレクティブでnginx + passengerを使用しています。 「静的アセット」には、アセットを提供するための動的URLがあるようです。これにより、次のスニペットのような特殊な場所のパスを介してnginxから直接コンテンツを提供するようにnginxを構成できなくなります。
# static content
location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|xml)$ {
# access_log off;
expires 15d;
}
これが正しい場合は、nginxの proxy_cache ディレクティブを使用することをお勧めします。これにより、nginxがパッセンジャーに行き、以前に要求されてキャッシュされたnginxが保存した応答を「再生成」する頻度を制御できます。 このサーバー障害の回答 は、使用方法を示すのに役立ちます。 proxy_cacheを使用すると、動的に生成された画像やjson/javascript/htmlコンテンツなどの応答をキャッシュできます。
memcached モジュールを試すこともできます。これにより、キャッシュをより細かく制御できます。これの欠点は、コードを入力してファイルをmemcacheに実際にプッシュする必要があることです。利点は、ある種類のmemcachedクラスターにコンテンツを集中的にキャッシュできることです。
私がインターウェブから収集したいくつかの追加ビットを上から続けます:
Rails 3.1の場合:
location ~* ^/assets/ {
# Per RFC2616 - 1 year maximum expiry
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
expires 1y;
add_header Cache-Control public;
# Some browsers still send conditional-GET requests if there's a
# Last-Modified header or an ETag header even if they haven't
# reached the expiry date sent in the Expires header.
add_header Last-Modified "";
add_header ETag "";
break;
}
Rails 3.0の場合
location ~* ^/(images|javascripts|stylesheets)/ {
... copy block from above ...
}
これをNGINX構成に追加してみてください:
server { ... location〜* ^/assets { expires max; add_header Cache-Control public; break; } ... }
まあ、これは古い質問であることは知っていますが、スタンドアロンのPassengerは次のように実行します。
# Rails asset pipeline support.
location ~ ^/assets/ {
error_page 490 = @static_asset;
error_page 491 = @dynamic_request;
recursive_error_pages on;
if (-f $request_filename) {
return 490;
}
if (!-f $request_filename) {
return 491;
}
}
location @static_asset {
gzip_static on;
expires max;
add_header Cache-Control public;
add_header ETag "";
}
location @dynamic_request {
passenger_enabled on;
}
多分あなたはrake assets:precompile
プリコンパイルされたアセットを/ public/assets /に貼り付けます