前言
当前Nginx 工作情况和新需求
- 当前 Nginx 工作情况:
- 所有的请求都按照一定规则进行重写然后转发服务器A。
- 新需求:
- 对请求进行过滤,符合某些格式的请求直接转发到服务器B
- 其他请求仍按原来的规则进行重写然后转发到服务器A。
当前Nginx配置
server {
listen 80;
server_name *.test.com;
set $city "";
if ( $host ~* "^(\w+)\.test\.com$") {
set $city $1;
}
rewrite ^/web/ $uri last;
rewrite ^/www/ $uri last;
rewrite ^/css/ $uri last;
rewrite ^/images/ $uri last;
rewrite ^/js/ $uri last;
rewrite ~*\.(css)$ www.test.com/$1 last;
rewrite ^/ajax/(\w+)/(\w+)$ /$1/$2 last;
rewrite ^/ctrl(\w+)/(\w+)\.html$ /$1/$2 last;
rewrite ^/ctrl(\w+)/(\w+)$ /$1/$2?city=$city last;
rewrite ^/ctrl(\w+)/(\w+)/(\w+)$ /$1/$2 last;
rewrite ^/(\w+)/(\w+)$ /$1/$2?city=$city last;
rewrite ^/(\w+)_(\w+)_(\w+)_(\w+)/index(\w+)\.html$ /city/index?city=$city&area=$1&type=$2&tab=$3&order=$4&p=$5? last;
rewrite ^/(\w+)_(\w+)_(\w+)_(\w+)/$ /city/index?city=$city&area=$1&type=$2&tab=$3&order=$4&p=1? last;
rewrite ^/(\w+)_(\w+)_(\w+)/index(\w+)\.html$ /city/index?city=$city&area=$1&type=$2&tab=$3&p=$4? last;
rewrite ^/(\w+)_(\w+)_(\w+)/$ /city/index?city=$city&area=$1&type=$2&tab=$3&p=1? last;
rewrite ^/* /city/index?city=$city&request_uri=$request_uri last;
if ($city = ""){
rewrite ^/* /;
}
error_page 404 /40x.html;
error_page 500 502 503 504 /50x.html;
location / {
proxy_set_header Host $host;
proxy_set_header Remote_Addr $remote_addr;
proxy_set_header X-REAL-IP $remote_addr;
proxy_connect_timeout 3;
proxy_send_timeout 30;
proxy_read_timeout 30;
proxy_pass http://area_jjzm_com;
}
}
满足新需求的配置
server {
listen 80;
server_name *.jjzm.com;
set $city "";
if ( $host ~* "^(\w+)\.jjzm\.com$") {
set $city $1;
}
set $uri_type "www_uri";
if ($request_uri ~* "^/seositemap/(.*)/(\w+).xml$"){
set $uri_type "seo_uri";
}
if ($request_uri ~* "^/(\w+)/seositemap/(.*)/(\w+).xml$"){
set $uri_type "seo_uri";
}
if ($uri_type ~ "www_uri"){
rewrite ^/web/ $uri last;
rewrite ^/www/ $uri last;
rewrite ^/css/ $uri last;
rewrite ^/images/ $uri last;
rewrite ^/js/ $uri last;
rewrite ~*\.(css)$ www.jzmmaoyan.com/$1 last;
rewrite ^/ajax/(\w+)/(\w+)$ /$1/$2 last;
rewrite ^/ctrl(\w+)/(\w+)\.html$ /$1/$2 last;
rewrite ^/ctrl(\w+)/(\w+)$ /$1/$2?city=$city last;
rewrite ^/ctrl(\w+)/(\w+)/(\w+)$ /$1/$2 last;
rewrite ^/(\w+)/(\w+)$ /$1/$2?city=$city last;
rewrite ^/(\w+)_(\w+)_(\w+)_(\w+)/index(\w+)\.html$ /city/index?city=$city&area=$1&type=$2&tab=$3&order=$4&p=$5? last;
rewrite ^/(\w+)_(\w+)_(\w+)_(\w+)/$ /city/index?city=$city&area=$1&type=$2&tab=$3&order=$4&p=1? last;
rewrite ^/(\w+)_(\w+)_(\w+)_(\w+)$ /city/index?city=$city&area=$1&type=$2&tab=$3&order=$4&p=1? last;
rewrite ^/(\w+)_(\w+)_(\w+)/index(\w+)\.html$ /city/index?city=$city&area=$1&type=$2&tab=$3&p=$4? last;
rewrite ^/job/(\w+)\.html$ /common/jobdetail?city=$city&id=$1? last;
rewrite ^/(\w+)_(\w+)_(\w+)/$ /city/index?city=$city&area=$1&type=$2&tab=$3&p=1? last;
rewrite ^/(\w+)_(\w+)_(\w+)$ /city/index?city=$city&area=$1&type=$2&tab=$3&p=1? last;
rewrite ^/* /city/index?city=$city&request_uri=$request_uri last;
}
if ($city = ""){
rewrite ^/* /;
}
error_page 404 /40x.html;
error_page 500 502 503 504 /50x.html;
location ~* ^/seositemap/(.*)/(\w+).xml$ {
proxy_set_header Host $host;
proxy_connect_timeout 3;
proxy_send_timeout 30;
proxy_read_timeout 30;
proxy_pass http://jzmao_timer;
}
location ~* ^/(\w+)/seositemap/(.*)/(\w+).xml$ {
rewrite ^/(\w+)/seositemap/(.*)/(\w+).xml$ /seositemap/$2/$3.xml break;
proxy_set_header Host $host;
proxy_connect_timeout 3;
proxy_send_timeout 30;
proxy_read_timeout 30;
proxy_pass http://jzmao_timer;
}
location / {
proxy_set_header Host $host;
proxy_set_header Remote_Addr $remote_addr;
proxy_set_header X-REAL-IP $remote_addr;
proxy_connect_timeout 3;
proxy_send_timeout 30;
proxy_read_timeout 30;
proxy_pass http://area_jjzm_com;
}
}
关键配置内容解析
- 通过 一个变量 $uri_type 来标记当前请求是否需要过滤
- 由于 Nginx 不支持嵌套的 if,也不支持 if 中使用逻辑运算符 ( &&),所以需要写多个 if。而不能简单写成:
- 正则表达式:
^/seositemap/(.*)/(\w+).xml$
^/seositemap/
:以 /seositemap/
开头(.*)
:中间有 n 层路径(\w+).xml
:以字符串.xml 结尾- 可匹配:
- /seositemap/sss/xxx/xxxx1.xml
- /seositemap/sss/xxx/xx/3333/xx1.xml
注意事项
if
和(
之间应该有空格,否则 Nginx 会把它们当成一个命令而导致报错