Подтвердить что ты не робот

Обслуживание предварительно скомпилированных активов с помощью nginx

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

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

Если это невозможно, я не понимаю всю идею с конвейерами Rails 3.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/*;

сайты с поддержкой/блог:

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;

    }

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

4b9b3361

Ответ 1

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

Ответ 2

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

Для 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 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 ...
}

Ответ 3

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

server {

  ...

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

  ...

}

Ответ 4

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

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

Ответ 5

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