用nginx区分文件大小做出不同响应

这篇博客讲述了如何利用nginx区分文件大小,为不同大小的文件设置不同的响应策略。在面对大文件下载场景时,由于squid在处理大文件时性能下降,采用两组服务器,一组用于小文件,一组用于大文件。通过分析请求的content-length,当超过阈值时,nginx返回302重定向到专门处理大文件的服务器。文中也探讨了使用http_perl_module扩展功能的可能性,以及如何进一步优化IP定向和负载均衡策略。
摘要由CSDN通过智能技术生成

昨晚和前21v的同事聊天,说到我离职后一些技术上的更新。其中有个给某大客户(游戏下载类)的特殊需求设计,因为文件大小差距很大——估计是大版本和补丁的区别——又走的是同一个域名,而squid在响应比较大的文件时,尤其是初次下载的时候,性能比较差,所以拆成两组服务器,squid服务于较小的文件,通过pull方式从peer层获取,nginx服务于较大的文件,通过push方式由peer层分发同步。外部发布域名一律解析到squid服务器组上,请求透传到peer层的nginx,nginx分析这个url的content-length,如果大于阈值,则不返回文件,而是302到nginx服务器组的独立域名下的相应url去。

这里要注意的是,nginx的内部变量里有一个$content-length,是不能用在这里的,官方wiki是这么解释这个变量的:”This variable is equal to line Content-Length in the header of request”。可见,这个变量是请求头的内容,一般见于POST请求用来限定POST信息的长度;而不是我们需要的响应头的内容。

老东家最后是修改了nginx的src完成的功能。不过我想,这里其实可以使用http_perl_module完成的。而且还可以扩展302跳转的功能,把独立域名改成直接通过remote_addr定向到最近IP上。

因为手头没有服务器,以下内容都是凭空想象,看官们注意…… 首先是nginx.conf里的配置:

http {
    perl_modules perl;
    perl_require SizeDiff.pm;
    server {
       listen       80;
       server_name  dl.gamedomain.com;
       location / {
          perl SizeDiff::handler;
       }
    }
}

然后是perl/SizeDiff.pm,如下:

package SizeDiff;
use Nginx::Simple;
sub main {
    my $self = shift;
    my $webroot = '/www/dl.gamedomain.com/'
    return HTTP_NOT_ALLOWED unless $self->uri =~ m!^(/.+/)[^/]+$!;
    my $file = $webroot . $1 . $self->filename;
    my @filestat = stat($file) or return HTTP_NOT_FOUND;
    my $filesize = $filestat[7];
    if ( $filesize < 8 * 1024 * 1024 ) {
        return OK;
    } else {
        $self->location('http://bigfile.cdndomain.com'.$self->uri);
    }
};
1

大体应该就是上面这样。 之前还考虑过如果不是push方式,可以在perl里考虑使用LWP获取header,不过仔细想想:第一,万一源站开启了chunked获取不到content-length呢?第二,就算可以,如果一个文件是1个G,那再去下载这1个G的文件下来,这个perl进程肯定挂了——官方wiki里可是连DNS解析时间都认为太长……也就是说,这个设想不适合在peer层,而是在loadbalance的角色,通过lwp的header结果,小文件upstream到后端的squid,大文件location到另外的nginx。 另一个可改进的地方,就是self->location前面,可以结合Net::IP::Match::Regexp模块或者自己完成的类似功能,来针对self->remote_addr选择最近的服务器组IP,最后返回location(“http://$ip$uri”)这样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值