使用nginx提供预编译资产

Jak*_*nes 35 ruby-on-rails nginx ruby-on-rails-3

是否可以直接使用nginx提供预编译资产?使用Rails动态提供资源的速度要慢20倍(4000 req/sec对比我的virtualbox中的200 req/sec).

我想这可以通过nginx.conf中的一些重写规则来完成.但问题是,这些文件名包含内容的md5哈希,所以我真的不明白可以用这个做什么.

如果不可能,我不会用Rails 3.1资产管道获得全部想法.以x20服务器负载为代价减少客户端带宽和页面加载时间?

有任何想法吗?

UPD:所以,当我的应用程序中的所有内容以~3500-4000个请求/秒的速度提供时,我设法以某种方式设置我的nginx和Rails .

首先,我添加了两个虚拟主机,其中一个作为另一个的缓存代理,发现资产以我想要的速度提供(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/*;
Run Code Online (Sandbox Code Playgroud)

网站启用/博客:

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;
        }
}
Run Code Online (Sandbox Code Playgroud)

/主启用网站 - :

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;

    }
Run Code Online (Sandbox Code Playgroud)

一切都像血腥的闪电一样快:)谢谢你,伙计们.

Ben*_*ing 35

从上面开始,我从互联网上收集了一些额外的信息:

对于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;
}
Run Code Online (Sandbox Code Playgroud)

对于Rails 3.0使用

location ~* ^/(images|javascripts|stylesheets)/ {
    ... copy block from above ...
}
Run Code Online (Sandbox Code Playgroud)

  • +1我只是用你的例子来解决我的问题.但是对于我的Rails 3.0.10应用程序,我不得不使用`location~*^ /(images | javascripts | stylesheets)/ {`代替.做得好! (2认同)
  • @NudeCanalTroll这与sprockets相关,而不是上面的NGINX代码.确保在部署期间运行资产编译 - rake资产:预编译 (2认同)

pct*_*ing 12

虽然我没有使用rails的经验,但我猜你是在使用带有proxy_pass指令的nginx + passenger.听起来你的"静态资产"有动态网址来提供资产,这会阻止你配置nginx直接从nginx通过专门的位置路径(如跟随代码段)提供内容:

#  static content
location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|xml)$ {
  # access_log        off;
  expires           15d;
}
Run Code Online (Sandbox Code Playgroud)

如果这是正确的,我的建议是尝试使用nginx的proxy_cache指令.这将让你控制nginx去乘客的频率,以"重新生成"先前请求和缓存的响应nginx.此服务器故障答案应该有助于您演示使用.使用proxy_cache,您可以缓存任何响应,例如动态生成的图像,甚至只是json/javascript/html内容.

您还可以尝试使用memcached模块,它将为您提供更精细的缓存控制.这方面的缺点是您必须实际将文件推送到内存中,并使用代码填充它.好处是,您可以在某种memcached集群中集中缓存您的内容.


bod*_*ous 6

尝试将此添加到您的NGINX配置:

server {

  ...

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

  ...

}