我在Ubuntu 8.04上使用Nginx 1.0.0和Passenger 3.0.7运行Rails 3站点。
在我的Nginx error.log中,我开始看到消息X-Accel-Mapping header missing
了很多。谷歌搜索引导我访问Rack::Sendfile
和Nginx docs的文档。
现在,我的应用可以通过多个域访问,并且我在我的应用中使用send_file
来提供特定于其请求的域的一些文件,例如,如果您来domain1.com/favicon.ico
我在public/websites/domain1/favicon.ico
查找favicon。
这工作正常,我认为我不需要/想要让Nginx参与并创建一些私有区域,我存储这些文件,如Rack::Sendfile
docs中的示例所示。
如何摆脱错误讯息?
答案 0 :(得分:15)
此消息表示Rack::Sendfile
已禁用X-Accel-Redirect
,因为您在nginx.conf中缺少配置...
我正在使用 Nginx + Passenger 3 + Rails 3.1 。
从这些页面收集的信息我已经弄明白了:
http://greenlegos.wordpress.com/2011/09/12/sending-files-with-nginx-x-accel-redirect
http://code.google.com/p/substruct/source/browse/trunk/gems/rack-1.1.0/lib/rack/sendfile.rb?r=355
Serving Large Files Through Nginx via Rails 2.3 Using x-sendfile
我有控制器将/download/1
请求映射到具有自己的目录结构的存储文件,如:storage/00/00/1
,storage/01/0f/15
等等。所以我需要通过Rails传递这个,但是然后我需要使用send_file
方法,该方法将使用X-Accel-Redirect
将最终文件直接发送到浏览器通过nginx 。
在代码中我有这个:
send_file(
'/var/www/shared/storage/00/00/01',
:disposition => :inline,
:filename => @file.name # an absolute path to the file which you want to send
)
我为此示例目的替换了文件名
现在我必须将这些行添加到nginx.conf
:
server {
# ...
passenger_set_cgi_param HTTP_X_ACCEL_MAPPING /var/www/shared/storage/=/storage/;
passenger_pass_header X-Accel-Redirect;
location /storage {
root /var/www/shared;
internal;
}
# ...
}
从外部世界看不到路径/storage
,它只是内部路径。
Rack::Sendfile
获取标题X-Accel-Mapping
,从中提取路径并将/var/www/shared/storage
替换为/storage...
。然后它吐出修改后的标题:
X-Accel-Redirect: /storage/00/00/01
然后由 nginx 处理。
我可以看到这个工作正常,因为文件的下载速度比之前快100倍,并且日志中没有显示错误。
希望这有帮助。
答案 1 :(得分:1)
我们使用了与 NoICE 类似的技术,但是我用包含所有文件的“硬编码”目录替换了描述包含文件夹的文件夹的正则表达式< / em>的
听起来很难,是吗?只需看看这些(/etc/nginx/sites-available/my.web.site
):
location /assets/(.+-[a-z0-9]+\.\w+) {
root /home/user/my.web.site/public/assets/$1;
internal;
}
location /images/(.+)(\?.*)? {
root /home/user/my.web.site/public/images/$1;
internal;
}
这应该与此检查一起使用:
location / {
# ...
if (-f $request_filename) {
expires max;
break;
}
# ...
}
防止Rails处理中的静态。
答案 2 :(得分:0)
我是按照这个手册做的
https://mattbrictson.com/accelerated-rails-downloads
我的服务器发送文件路径/private_upload/file/123/myfile.txt
,文件在/data/myapp-data/private_upload/file/123/myfile.txt
# Allow NGINX to serve any file in /data/myapp-data/private_upload
# via a special internal-only location.
location /private_upload {
internal;
alias /data/myapp-data/private_upload;
}
# ---------- BACKEND ----------
location @backend
{
limit_req zone=backend_req_limit_per_ip burst=20 nodelay;
proxy_pass http://backend;
proxy_set_header X-Sendfile-Type X-Accel-Redirect;
proxy_set_header X-Accel-Mapping /=/; # this header is required, it does nothing
include /etc/nginx/templates/myapp_proxy.conf;
}