是否可以直接使用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/*;
/博客网站启用 - :
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;
}
一切都像血腥闪电一样快:) 谢谢你们,伙计们。
答案 0 :(得分:34)
从上面开始,我从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'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 ...
}
答案 1 :(得分:11)
虽然我没有使用rails的经验,但我猜你是在使用带有proxy_pass指令的nginx + passenger。听起来你的“静态资产”有动态网址来提供资产,这会阻止你配置nginx直接从nginx通过专门的位置路径提供内容,如以下代码段:
# static content
location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|xml)$ {
# access_log off;
expires 15d;
}
如果这是正确的,我建议您尝试使用nginx的proxy_cache指令。这将让你控制nginx去乘客“重新生成”以前保存的请求和缓存的响应nginx的频率。 This server fault answer应该帮助您展示使用方法。使用proxy_cache,您可以缓存任何响应,例如动态生成的图像,甚至只是json / javascript / html内容。
您还可以尝试memcached模块,它将为您提供更精细的缓存控制。这方面的缺点是您必须实际将文件推送到内存中,并使用代码填充它。好处是,您可以在某种memcached集群中集中缓存您的内容。
答案 2 :(得分:5)
尝试将此添加到您的NGINX配置中:
server { ... location ~* ^/assets { expires max; add_header Cache-Control public; break; } ... }
答案 3 :(得分:2)
嗯,我知道这是一个老问题,但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;
}
答案 4 :(得分:1)
也许你应该运行rake assets:precompile
它会将预编译资产粘贴在/ public / assets /