Nginx技巧:如何使用X-Accel-Redirect同时输出ETag Header和其他自定义Header

在Nginx中,常见的技巧是后端fastcgi使用X-Accel-Redirect Header来通知nginx使用sendfile加速
文件的输出,避免后端重复读取文件.
当使用X-Accel-Redirect时, 后端输出的一些自定义header就被忽略掉了. 在upstream redirect到
内部location uri后, 这些header并没有被同时输出.

这2天,为了快速解决PHP的性能问题, 就用Perl做的一个Plack application, 用于dispatch MongoDB中的gridfs. 为了加速, 对于gridfs的文件
进行了cache, 并根据文件的md5值输出etag. 这样,当client 请求时, 如果mongodb中的主文件的md5
并没有改变,那么就直接输出304. 否则使用X-Accel-Redirect返回cache file的uri.
使用ETag的原因就是cache文件需要频繁清理, 仅仅依靠last modified time并不可靠.
, Plack的应用也是可以负载到不同的fastcgi upstream.
ETag的验证机制则可以很好的解决这些问题.
因为有很多文件其实很少读取的, 即便某些用户偶然访问, 那么通过ETag如果验证文件在MongoDB中
并没有变动,则直接返回304即可, 无需再重新创建cache文件,从而可以保持cache的热度.

如何能够输出ETag呢, 解决方式就是在X-Accel-Redirect 定向到的location中,使用add_header来
设置附加的ETag header:

location /__file_result__ {
internal;
root /cache;
add_header ETag $upstream_http_etag;
}

这样, 对应的X-Accel-Redirect的文件就有了对应的ETag header.
实际上, 你可以使用add_header加入其他更多的HEADER. 对应的$upstream_http_(header_name).
变量的格式可以在手册的upstream模块部分查到.

BTW, Plack 的效率和性能还是很爽的. 开发效率很高, 10几分钟就能完成一个高效的fastcgi应用.
相对以前手工写, 进步了一大块. 尤其是当你只是想解决几个小问题的时候,相比之下,Cgi::Application都像牛刀了.

Comments

Leave a Reply