一个nginx配置小问题


【结论】
目前的配置,可以完成基本的功能,但使nginx要处理的请求的数量,增加了一倍(下面详述),所以,要尽可能避免像目前这样配置,可以有更合适的配置。


【要实现的功能】
使客户端发起的类似http://cq01-testing-ibase11.vm.baidu.com:8080/lightapp/1767031这样的请求,首先变成http://cq01-testing-ibase11.vm.baidu.com:8080/lightapp/locate/1767031这样,然后再由php-fcgi处理。


【目前的配置】

在rewrites.conf中,增加两条重写规则,依次如下:
rewrite ^/lightapp/([0-9]+)$ /lightapp/locate/$1 last;
rewrite ^/lightapp(/.*)$ /phpsrc/lightapp/index.php last;

在php.conf中,增加一个location:
location ^~ /lightapp/ {
    proxy_pass  http://127.0.0.1:8080 ;
    break;
}

这样配置的问题,如开头所述。即当客户端发起一个请求时,nginx为完成客户端的请求,实际处理了两个完整的请求。这两个请求的区别是,一个来自客户端,最后把请求代理到本机8080端口上的进程,也就是nginx;一个来自nginx所在的机器,最后把请求代理到php-fcgi。总之,nginx工作量增加了一倍。


【更好的配置】

在rewrites.conf中,只增加一条重写规则,即上面的第一条重写规则:
rewrite ^/lightapp/([0-9]+)$ /lightapp/locate/$1 last;

在php.conf中,有两种配置方式,第一种如下:

location ^~ /lightapp/ {
    fastcgi_pass fpm_us;
    include fastcgi_params;
    fastcgi_param REQUEST_URI $uri; #重点在这里
    fastcgi_param SCRIPT_FILENAME $document_root/phpsrc/lightapp/index.php;
    break;
}

思路就是,让客户端发给nginx的请求,经nginx server rewrite后,直接请求php-fcgi,以此来避免第二次相同的请求。

但这种配置的一个问题是,当有很多类似的需求时,就需要多次重复写上面的nginx fastcgi module的指令,很不方面。所以,有了下面的第二种配置方式:

在nginx.conf或者php.conf中,http {}内、所有server {}外:
map $kw $my_script {
    default /phpsrc/developer/index.php;
    lightapp /phpsrc/lightapp/index.php;
}

location ^~ /lightapp/ {
    set $kw lightapp;
    try_files $uri @normalized_request_uri;
}

#以下named location可以重用
location @normalized_request_uri {
    fastcgi_pass fpm_us;
    include fastcgi_params;
    fastcgi_param REQUEST_URI $uri;
    fastcgi_param SCRIPT_FILENAME $document_root$my_script;
    break;
}


【其他】
乍一想,用nginx的rewrite指令,或者ngx_lua的ngx.exec或ngx.location.capture等api,可以有看似更简单的配置方式,这些配置方式我不一一列举了。但由于以下原因,这些配置方式其实都不可行:

1) 最根本的,nginx的$request_uri变量是read-only的
2) rewrite的第一个参数,依据是raw uri,而不是normalized uri;而location依据的是normalized uri
3) 在fastcgi_params配置文件中,把fcgi的环境变量REQUEST_URI的值,写死了为nignx的$request_uri变量的值。这满足绝大多数的需求和场景

4) 在php程序中,用了$_SERVER['REQUEST_URI']来取得请求的uri,这其实是很合理的

-----------------------


【临时方案】

好处是,新增配置语句简单,好理解;坏处是,扩展性很差。

在rewrites.conf中,只需要以下这一句配置,多余的去掉:
rewrite ^/lightapp/([0-9]+)$ /lightapp/locate/$1 last;

在php.conf中,增加以下配置语句:
location ^~ /lightapp/ {
    fastcgi_pass fpm_us;
    include fastcgi_params;
    fastcgi_param REQUEST_URI $uri; #重点在这里 
    fastcgi_param SCRIPT_FILENAME $document_root/phpsrc/lightapp/index.php;
    break;
}


【长期方案】

好处是,扩展性好;坏处是,增加的配置语句多(但仅仅是这一次多,以后就简单了),复杂。

在rewrites.conf中,只需要以下这一句配置,多余的去掉:
rewrite ^/lightapp/([0-9]+)$ /lightapp/locate/$1 last;

在nginx.conf中,http {} block内,增加以下配置语句:
map $kw $my_script {
    default /phpsrc/developer/index.php;
    lightapp /phpsrc/lightapp/index.php;
}

在php.conf中,第一个server {} block内(即目前的php.conf中,最重要的那个server block),增加以下配置语句:

location ^~ /lightapp/ {
    set $kw lightapp;
    try_files $uri @normalized_request_uri;
}

#以下named location可以重用
location @normalized_request_uri {
    fastcgi_pass fpm_us;
    include fastcgi_params;
    fastcgi_param REQUEST_URI $uri;
    fastcgi_param SCRIPT_FILENAME $document_root$my_script;
    break;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值