web-dev-qa-db-ja.com

nginxでプリコンパイルされたアセットを提供する

プリコンパイルされたアセットを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;

    }

すべては血まみれの稲妻のように高速です:)ありがとうございます。

35
Jake Jones

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クラスターにコンテンツを集中的にキャッシュできることです。

12
pcting

私がインターウェブから収集したいくつかの追加ビットを上から続けます:

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 ...
}
35
Ben Walding

これをNGINX構成に追加してみてください:

 server {
 
 ... 
 
 location〜* ^/assets {
 expires max; 
 add_header Cache-Control public; 
 break; 
} 
 
 ... 
 
} 
6
bodacious

まあ、これは古い質問であることは知っていますが、スタンドアロンの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;
    }
2
James Lim

多分あなたはrake assets:precompileプリコンパイルされたアセットを/ public/assets /に貼り付けます

1
Tom van Leeuwen