Обслуживание предварительно скомпилированных активов с помощью nginx - PullRequest
34 голосов
/ 19 июня 2011

Можно ли обслуживать предварительно скомпилированные активы с помощью nginx напрямую?Динамическое обслуживание ресурсов с помощью Rails примерно в 20 раз медленнее (4000 рэк / сек против 200 рэк / сек в моей виртуальной коробке).

Я думаю, это можно сделать с помощью некоторого правила перезаписи в nginx.conf.Проблема, однако, в том, что эти имена включают в себя хэш содержимого md5, поэтому я не совсем понимаю, что можно сделать с этим.

Если это невозможно, я не получаю полной идеи с Rails3.1 Актив трубопроводов.Сокращение пропускной способности клиента и времени загрузки страницы за счет нагрузки на сервер x20?

Есть идеи?

UPD: Итак, мне удалось настроить nginx и Rails таким образом, когда все в моем приложении обслуживается со скоростью ~ 3500-4000 запросов / сек.

Прежде всего я добавил два виртуальных хоста, один из которых служил прокси-сервером для кэширования, и обнаружил, что ресурсыслужил на скорости, которую я хотел (4k).Затем я связал свое приложение Rails с memcached (пока ничего особенного, только одна строка в application.rb: 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/*;

sites-enabled / blog:

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;
        }
}

sites-enabled / main:

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;

    }

Все быстро, как кровавая молния :) Спасибо, ребята.

Ответы [ 5 ]

34 голосов
/ 14 сентября 2011

Исходя из некоторых дополнительных битов, которые я почерпнул из паутины:

Для 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 ...
}
11 голосов
/ 20 июня 2011

Хотя у меня нет опыта работы с рельсами, я предполагаю, что вы используете nginx + passenger с директивой proxy_pass.Похоже, у ваших «статических ресурсов» есть динамические 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.

5 голосов
/ 20 июня 2011

Попробуйте добавить это в вашу конфигурацию NGINX:

server {

  ...

  location ~* ^/assets {
    expires max;
    add_header Cache-Control public;
    break;
  }

  ...

}
2 голосов
/ 08 июня 2013

Ну, я знаю, что это старый вопрос, но автономный Пассажир делает это следующим образом:

    # 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;
    }
1 голос
/ 05 июля 2011

, возможно, вам следует запустить rake assets:precompile. Он поместит предварительно скомпилированные ресурсы в / public / assets /

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...