`
xupo
  • 浏览: 212086 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Nginx与sendfile

阅读更多

lighttpd 有一个 X-Sendfile 的特性很有意思。比如传统的做一些需要严格验证的下载之类的功能比如收费下载,需要在程序里验证权限,然后由程序读取文件输出,这样性能不好,占用资源也大,而 web server 本身的功能又不足以提供验证。使用 X-Sendfile 就可以让程序来做验证,而把文件传输交给 web server 来做,各自做各自擅长的事情。

本来以为这功能目前就 lighttpd 有,今天发现原来 nginx 也有这能力,apache 也可以通过第三方模块来实现。

nginx 上这个功能叫做 X-Accel-Redirect 。

假设下载文件的路径在 /path/to/files,比如有 /path/to/files/test1.txt 可以在 nginx 里配置

location /down {
     internal;
     alias   /path/to/files;
}

internal 选项是这个路径只能在 nginx 内部访问。

然后可以在 php 里写

header("X-Accel-Redirect: /down/test1.txt");

就可以了。

另外,如果在程序那头如果不想要开头的那个“/”,比如想写成 header("X-Accel-Redirect: down/test1.txt"); ,那么在 nginx 的那条 alias 的最后就要加一个 “/”。

 

什么是sendfile?
nginx官方只是一句带过,如果你需要了解详细的请参考: http://celebnamer.celebworld.ws/stuff/mod_xsendfile/

为什么要用sendfile?
原因很简单,项目中有个需求是后端程序负责把源文件打包加密生成目标文件,然后程序读取目标文件返回给浏览器;这种做法有个致命的缺陷就是占用大量后端程序资源,如果遇到一些访客下载速度巨慢,就会造成大量资源被长期占用得不到释放,很快后端程序就会因为没有资源可用而无法正常提供服务。通常表现就是nginx报502错误!其次在nginx内部我还想实现“由nginx检查目标文件是否存在,如果存在的话就直接返回给浏览器而无需经过后端程序的处理”,这样一来后端程序只是负责生成目标文件,一单目标文件被生成,基本上就不再提供服务,而nginx则提供全静态的文件浏览服务。可想而知,性能的提升还是大很多的!

怎么启用sendfile?
详细配置步骤就不说了,官方wiki已经说明的比较清楚。只提一下注意点吧:
1,location 必须 被定义为 internal;
2,如果在location中使用alias 一定要注意目录结尾的“/”;
3,要注意location 匹配时尽量只用目录名。 我在测试中遇到抓狂的问题。

先说一下我最终的方案:
1,增加一个location作为目标文件的检查,如果存在 就发给internal的location继续处理,如果不存在就rewrite到后端程序处理;

location ~ ^/vdir/(.*)\.ext$
{
    set $obj_file "$1.ext";
    if (!-f /path/to/obj/dir/$obj_file)
    {
        rewrite ^  /backend/app last;
    }
    rewrite ^ /revdir/$obj_file last;
}

以上代码可实现“由nginx检查目标文件是否存在,如果存在的话就直接返回给浏览器而无需经过后端程序的处理”。
接下来看下sendfile相关的location

location /revdir
{
    internal;
    alias /another/dir/;
    #rewrite (.*) /$1 redirect; # 用于测试匹配到的数据是否正确,也可以使用 add_header  xxx  $1  来代替
}

程序里送出的header是 :

X-Accel-Redirect: /revdir/a/b/xxx.ext

需要再原本的文件路径前加一个虚拟目录 /revdir/

下面讲一下访客在浏览 http://yourdomain/vdir/d/i/r/xxx.ext时的一些处理过程:
1,nginx会先去检查是否存在目标文件”/path/to/obj/dir/d/i/r/xxx.ext”
2.1,如果文件不存在,就会发起一个rewrite ,将请求发往后端程序处理生成文件,然后后端程序只送出”X-Accel-Redirect”header之后完成处理,nginx接受X-Accel-Redirect会被 location /revdir 匹配到,继而发送该文件;
2.1,如果文件存在,也会发起一个rewrite ,然后会被 location /revdir 匹配到,继而直接发送该文件无需经过后端程序;
3,over.

提醒注意:
如果你在测试中发现nginx报500,首先一个考虑下是不是重复匹配次数达到nginx内部预设的10次上限,然后报500错误。有方法可以验证,适当的location添加:

log_subrequest on;

详细请点击参考官方wiki

最后再提一点,远程文件怎么使用这个功能来转发呢? 不是proxy喔~~
有兴趣的可以参考这里:Nginx-Fu: X-Accel-Redirect From Remote Servers

分享到:
评论

相关推荐

    在Nginx中使用X-Sendfile头提升PHP文件下载的性能(针对大文件下载)

    很多时候用户需要从网站下载文件,如果文件是可以通过一个固定链接公开获取的,那么我们只需将文件存放到 ... $file = determine_file(); // 读取文件内容 $content=file_get_contents($file); //

    nginx配置教程

    #sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件, #对于普通应用,必须设为 on, #如果用来进行下载等应用磁盘IO重负载应用,可设置为 off, #以平衡磁盘与网络I/O处理速度,降低...

    决战Nginx系统卷:高性能Web服务器详解与运维第一部分(保证能用)

    第25章 Nginx与X-Sendfile 第26章 在Nginx的响应体之前或之后添加内容 第27章 Nginx与访问者的地理信息 第28章 Nginx的图像处理 第29章 location中随机显示文件 第30章 后台Nginx服务器记录原始客户端的IP地址 ...

    决战Nginx系统卷:高性能Web服务器详解与运维第二部分(保证能用)

    第25章 Nginx与X-Sendfile 第26章 在Nginx的响应体之前或之后添加内容 第27章 Nginx与访问者的地理信息 第28章 Nginx的图像处理 第29章 location中随机显示文件 第30章 后台Nginx服务器记录原始客户端的IP地址 ...

    决战Nginx: 系统卷 - 高性能Web服务器详解与运维第三部分(保证能用)

    第25章 Nginx与X-Sendfile 第26章 在Nginx的响应体之前或之后添加内容 第27章 Nginx与访问者的地理信息 第28章 Nginx的图像处理 第29章 location中随机显示文件 第30章 后台Nginx服务器记录原始客户端的IP地址 ...

    nginx:使用Ansible设置Nginx服务器

    Nginx的 设置具有配置域名的nginx服务HTTPS。 要求 基于apt的软件包管理器和systemd 角色变量 角色变量 默认 描述 nginx_install_full_package ... 是否安装nginx-full软件包而不是普通的nginx... nginx_sendfile on

    nginx 1.9 window 版本

    #sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,对于普通应用, #必须设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,以平衡磁盘与网络I/O处理速度,降低系统的...

    nginx.conf

    user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn;... sendfile on;  #tcp_nopush on;  keepalive_timeout 65;  #gzip on;  include /etc/nginx/conf.d/*.conf;

    nginx安装及配置

    Nginx的基本架构: master/worker 一个master进程,可生成一个或多个worker进程; master:加载配置文件、管理worker进程、平滑升级…… ... 事件驱动:epoll(Linux), ... 支持sendfile, sendfile64 支持AIO,mmap

    服务器端nginx配置文件

    sendfile on; #设置长连接 keepalive_timeout 65; #配置共享会话缓存大小 ssl_session_cache shared:SSL:10m; #配置会话超时时间 ssl_session_timeout 10m; #最大数据长度 client_max_body_size 200m;...

    Nginx+Tomcat负载均衡

    sendfile on; tcp_nopush on; tcp_nodelay on; #keepalive_timeout 75 20; include gzip.conf; upstream localhost { #ip_hash #ip_hash; server localhost:8081; server localhost:8080; } ...

    nginx配置文件祥解

    client_body_timeout 3m; send_timeout 3m; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65;

    nginx.conf.txt

    #user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log ... sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65;

    详解Nginx 出现 403 Forbidden 的解决办法

    Nginx 也是当前流行的一款 轻量级服务器 在日常使用中呢 也会出现一些问题 今天 学习君 在安装配置Nginx的时候就出现了 403 Forbindden 的被禁止访问的错误 网上搜索之后呢 完美解决 这里给... sendfile on; aut

    Nginx中部署Angular项目遇到的坑巨坑

    网上搜索Angular 项目编译后部署到 Nginx 中的方法,多数文章都介绍... #sendfile on; #charset koi8-r; access_log /var/log/nginx/host.access.log main; location / { root /chanchaw/app/angular; index index

    nginx修改上传文件大小限制的方法

    新装了一台服务器,用nginx做代理。突然发现上传超过1M大的客户端文件无法正常上传,于是修改了下nginx的配置。 cd /export/servers/nginx/conf/nginx.conf,在这个配置文件里面的server段里面的 ...sendfile on; #tcp

    nginx-conf-for-rails:本页描述了 Nginx with Rails 的配置(示例)(通过 Unicorn)

    Rails 的 Nginx 配置 本页描述了 Nginx 与 Rails(通过 Unicorn)的配置(示例)。 nginx /etc/nginx/nginx.conf worker_processes 8 ; user nobody nobody; events { worker_connections 4096 ;... sendfile on

    Nginx服务器搭建和基本配置详解

    例如在 Linux 系统上,Nginx 使用了 epoll,sendfile,File AIO,DIRECTIO 等机制,使得 Nginx 不仅性能高效,而且资源占用率非常低,官方宣称 nginx 维持 10000 个非活动的 HTTP keep-alive 连接仅需要 2.5M 内存。...

    tomcat8 + nginx + memcached + cas 实现负载均衡的配置包

    sendfile on; tcp_nopush on; tcp_nodelay on; #keepalive_timeout 0; keepalive_timeout 65; gzip on; #设定负载均衡的服务器列表 upstream 127.0.0.1 { #设定负载均衡的服务器列表 #ip_hash; ...

Global site tag (gtag.js) - Google Analytics