Nginx优化之rewrite模块

Nginx优化之rewrite模块

前言

Nginx具有的特色之一就是rewrite模块,这个模块是什么?rewrite模块有什么作用?

接下来就来说说rewrite跳转的场景(仅一部分)

1.URL看起来更规范、合理

2.企业将动态URL地址伪装成静态地址提供服务

3.网址换新域名后,让旧的访问跳转到新的域名上

4.服务端某些业务的调整

下面我们就来看看rewrite模块跳转吧!

1.rewrite模块如何实现跳转

首先,rewrite是集成在nginx_http_rewrite_module模块中的,而nginx_http_rewrite_module模块是nginx装完后就自带的,所以,我们没有必要再装这个模块了,下面我们来看看如何实现跳转。

1.nginx:支持URL重写、支持if条件判断,但不支持else

2.跳转:循环最多可以执行10次,超过10次后nginx将返回500错误

3.pcre支持、重写set模块命令:rewrite使用nginx全局变量或自己设置变量,结合正则表达式和标志位实现URL重写以及重定向

nginx跳转需求的实现方式

1.使用rewrite进行匹配跳转

2.使用if匹配全局变量后跳转

3.使用location匹配再跳转

rewrite可以放在 server{} ,if{} , location{}段中

2.rewrite和location

1.常用的正则表达式元字符

字符 说明
^ 匹配输入字符串的起始位置
$ 匹配输入字符串的结束位置
* 匹配前面的字符零次或多次
+ 匹配前面的字符一次或多次
? 匹配前面的字符零次或一次
. 匹配除“\n”之外的任何单个字符。使用诸如"[.\n]"之 类的模式,可匹配包括^n”在内的任意字符
\ 将后面接着的字符标记为一一个特殊字符或一个原 义字符或一 个向后引用
\d 匹配纯数字
{n} 重复n次
{n,} 重复n次或更多次
[c] 匹配单个字符c
[a-z] 匹配a-z小写字母的任意一个
[a-zA-Z] 匹配a-z小写字母或A-Z大写字母的任意一个

2.rewrite命令详解

rewrite <regex> <replacement> [flag];

正则表达式

跳转后的内容

[flag] rewrite支持flag标记

flag标记说明

标记 说明
last 相当于Apache的[L]标记,表示完成rewrite
break 本条规则匹配完成即终止,不再匹配后面的任何规则
redirect 返回302临时重定向,浏览器地址会显示跳转后的URL地址,爬虫不会更新url
permanent 返回301永久重定向,浏览器地址栏会显示跳转后的URL地址,爬虫更新url

last和break比较

last
使用场景 一般写在server和if中 一般使用在location中
URL匹配 不终止重写后的url匹配 终止重写后的url匹配

3.location的分类

location = patt {} [精准匹配]
lacation patt {} [一般匹配]
location ~ patt {} [正则匹配]

正则匹配的常用表达式

标记 说明
~ 执行一个正则匹配,区分大小写
~* 执行一个正则匹配,不区分大小写
!~ 执行一一个正则匹配,区分大小写不匹配
!~* 执行一个正则匹配,不区分大小写不匹配
^~ 普通字符匹配;使用前缀匹配。如果匹配成功,则不再匹配其他location
= 普通字符精确匹配。也就是完全匹配
@ 定义一个命名的location,使用在内部定向时

4.location的优先级

1.相同类型的表达式,字符串长的会优先匹配

2.优先级排序

=类型
^~类型表达式
正则表达式(~和~*)类型
常规字符串匹配类型,按前缀匹配
通用匹配(/),如果没有其他匹配,任何请求都会匹配到

5.比较rewrite和location

相同点

都能实现跳转

不同点

1.rewrite是在同一域名内更改获取资源的路径

2.location是对一类路径做访问控制或反向代理,还可以proxy_pass到其他机器

rewrite会写在location里,执行顺序如下

1.执行server块里面的rewrite指令

2.执行location匹配

3.执行选定的location中的rewrite指令

6.location优先级示例

location = / {
[ configuration A ]
}
精确匹配/,主机名后面不能带任何字符串

location / {
[ configuration B ]
}
所有的地址都以/开头,这条规则将匹配到所有请求,但正则和最长字符串会优先匹配

location /documents/ {
[ configuration C ]
}
匹配任何以/documents/开头的地址,当后面的正则表达式没有匹配到时,才起作用

location ~ /documents/abc {
[ configuration D ]
}
匹配任何以/documents/abc开头的地址,当后面的正则表达式没有匹配到时,才会起作用

location ^~ /images/ {
[ configuration E ]
}
以/images/为开头的地址,匹配符合后,停止往下匹配

location ~* \.(gif|jpg|jpeg)$ {
[ configuration F ]
}
匹配所有以gif,jpg或jpeg结尾的请求,/images/下的图片会被[ configuration E ]处理,因为^~的优先级更高

location /images/abc {
[ configuration G ]
}
最长字符匹配到/images/abc,优先级最低

location ~ /images/abc {
[ configuration H ]
}
以/images/abc开头的,优先级次之

location /images/abc/1.html {
[ configuration I ]
}
如果和正则~ /images/abc/1.html相比,正则的优先级更高

7.location优先级规则

1.匹配某个具体文件

(location = 完整路径)> (location ^~ 完整路径) > (location ~* 完整路径) > (location ~ 完整路径) > (location 完整路径) > (location /)

2.用目录作匹配访问某个文件

(location = 目录) > (location ^~ 目录/) > (location ~ 目录) > (location ~* 目录) > (location 目录) > (location /)

3.rewrite和location示例

1.基于域名的跳转

需求:

公司旧域名www.hello.com,因业务需要,需要使用新的续命www.newhello.com

1.不能废除旧域名

2.从旧域名跳转到新域名,且保持其参数不变

实验步骤

1.我们先安装nginx的rpm的官方环境包,然后安装dns域名服务

[root@localhost ~]# rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
获取http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
警告:/var/tmp/rpm-tmp.uZp3Qz: 头V4 RSA/SHA1 Signature, 密钥 ID 7bd9bf62: NOKEY
准备中...                          ################################# [100%]
正在升级/安装...
   1:nginx-release-centos-7-0.el7.ngx ################################# [100%]
//这一步是连接到nginx的官方网站,我们yum安装nginx必须要先安装这个
[root@localhost ~]# yum -y install nginx  //yum安装nginx
[root@localhost ~]# yum -y install bind   //安装域名解析服务

2.我们先配置dns域名解析服务

[root@localhost ~]# vim /etc/named.conf
        listen-on port 53 { any; };
		allow-query     { any; };
[root@localhost ~]# vim /etc/named.rfc1912.zones
zone "hello.com" IN {
        type master;
        file "hello.com.zone";
        allow-update { none; };
};

zone "newhello.com" IN {
        type master;
        file "newhello.com.zone";
        allow-update { none; };
};
[root@localhost ~]# cd /var/named/
[root@localhost named]# ls
data  dynamic  named.ca  named.empty  named.localhost  named.loopback  slaves
[root@localhost named]# ls
data  dynamic  hello.com.zone  named.ca  named.empty  named.localhost  named.loopback  slaves
[root@localhost named]# vim hello.com.zone 

$TTL 1D
@       IN SOA  @ rname.invalid. (
                                        0       ; serial
                                        1D      ; refresh
                                        1H      ; retry
                                        1W      ; expire
                                        3H )    ; minimum
        NS      @
        A       127.0.0.1
www IN  A       192.168.73.224
[root@localhost named]# cp -p hello.com.zone newhello.com.zone

3.重启dns域名服务和nginx服务,并在win10主机里面测试

[root@localhost named]# systemctl stop firewalld
[root@localhost named]# setenforce 0
[root@localhost named]# systemctl restart named
[root@localhost named]# systemctl restart nginx
[root@localhost named]# netstat -ntap | grep 80
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      3159/nginx: master  
[root@localhost named]# netstat -ntap | grep 53
tcp        0      0 192.168.73.224:53       0.0.0.0:*               LISTEN      3121/named          
tcp        0      0 127.0.0.1:53            0.0.0.0:*               LISTEN      3121/named          
tcp        0      0 192.168.122.1:53        0.0.0.0:*               LISTEN      1466/dnsmasq        
tcp        0      0 127.0.0.1:953           0.0.0.0:*               LISTEN      3121/named          
tcp        0      0 192.168.73.224:37930    199.7.91.13:53          TIME_WAIT   -                   
tcp        0      0 192.168.73.224:42369    199.7.91.13:53          TIME_WAIT   -                   
tcp6       0      0 ::1:53                  :::*                    LISTEN      3121/named          
tcp6       0      0 ::1:953                 :::*                    LISTEN      3121/named

给win10主机配置dns域名的地址

在这里插入图片描述

在cmd中测试lookup

在这里插入图片描述

在浏览器中输入域名

在这里插入图片描述

4.修改主配置文件,将基于域名的跳转写入主配置文件,修改完主配置文件后记得重启nginx服务

[root@localhost ~]# vim /etc/nginx/conf.d/default.conf
    location / {
        if ($host = 'www.hello.com') {
                rewrite ^/(.*)$ http://www.hello.com/$1 permanent;
        }
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
[root@localhost ~]# systemctl restart nginx

5.在win10主机里面测试

输入www.newhello.com

在这里插入图片描述

输入www.hello.com

在这里插入图片描述

2.允许合法ip访问页面

需求:

今天公司业务版本上线,所有IP访问内容都显示一个固定维护页面,只有公司IP访问正常。

实验步骤

1.我们依旧使用上面的环境,下面我们开始修改主配置文件,并在nginx的站点创建维护网页。

[root@localhost ~]# vim /etc/nginx/conf.d/default.conf
    if ($remote_addr = "ip") {
        set $rewrite false;
    }   

    if ($rewrite = true) {
        rewrite (.+) /maintaining.html;
    }   

    location = /maintaining.html {
        root     /usr/share/nginx/html;
    }

    location / {
        //将刚刚写的基于域名的部分注释掉
        #if ($host = 'www.hello.com') {
        #       rewrite ^/(.*)$ http://www.hello.com/$1 permanent;
        #}
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
[root@localhost ~]# cd /usr/share/nginx/html
[root@localhost html]# ls
50x.html  index.html
[root@localhost html]# vim maintaining.html
<h1>Sorry , this web is maintaining , please wait for a moment! </h1>
[root@localhost html]# systemctl restart nginx

2.在win10主机里面测试

输入域名www.hello.com

在这里插入图片描述

3.基于旧域名转到新域名后面加目录

需求:

公司由于业务变更,公司的域名为bbs.hello.com变更为www.hello.com

实验步骤

1.修改主配置文件

[root@localhost html]# vim /etc/nginx/conf.d/default.conf 
    #set $rewrite true;

    #if ($remote_addr = "ip") {
    #   set $rewrite false;
    #}

    #if ($rewrite = true) {
    #    rewrite (.+) /maintaining.html;
    #}

    #location = /maintaining.html {
    #    root     /usr/share/nginx/html;
    #}
    location /post {
         rewrite (.+) http://www.hello.com/bbs$1 permanent;
    }

2.修改主配置文件

[root@localhost html]# cd /var/named
[root@localhost named]# ls
data     hello.com.zone  named.empty      named.loopback     slaves
dynamic  named.ca        named.localhost  newhello.com.zone
[root@localhost named]# vim hello.com.zone 

$TTL 1D
@       IN SOA  @ rname.invalid. (
                                        0       ; serial
                                        1D      ; refresh
                                        1H      ; retry
                                        1W      ; expire
                                        3H )    ; minimum
        NS      @
        A       127.0.0.1
bbs IN  A       192.168.73.224

3.重启服务

[root@localhost named]# systemctl restart named
[root@localhost named]# systemctl restart nginx

4.我们在win10主机里面测试

在这里插入图片描述

按下回车后,我们来看看结果

在这里插入图片描述

4.基于多参数匹配、不同页面、指定页面的跳转

需求:

当访问某些页面的时候,我们不希望对面继续访问下去,我们就让网页直接跳到主页面

实验步骤

1.修改主配置文件

[root@localhost named]# vim /etc/nginx/conf.d/default.conf
    #location /post {
    #     rewrite (.+) http://www.hello.com/bbs$1 permanent;
    #}
    #location /post {
    #     rewrite (.+) http://www.hello.com/bbs$1 permanent;
    #}

//基于多参数的跳转,将www.hello.com/100-100-100.html跳转到首页
    if ($request_uri ~ ^/100-(100|200)-(\d+).html$){
        rewrite (.*) http://www.hello.com permanent;
    }

//基于不同页面的跳转,将www.hello.com/upload/目录下面的.php结尾的文件自动跳转到www.hello.com
    location ~* /upload/.*\.php$ {
        rewrite (.+) http://www.hello.com permanent;
    }

//基于指定页面的跳转,将www.hello.com/abc/123.html页面跳转到www.hello.com
    location ~* ^/abc/123.html {
        rewrite (.+) http://www.hello.com permanent;
    }
[root@localhost named]# vim hello.com.zone 
$TTL 1D
@       IN SOA  @ rname.invalid. (
                                        0       ; serial
                                        1D      ; refresh
                                        1H      ; retry
                                        1W      ; expire
                                        3H )    ; minimum
        NS      @
        A       127.0.0.1
www IN  A       192.168.73.224

2.重启服务

[root@localhost named]# systemctl restart named
[root@localhost named]# systemctl restart nginx

3.在win10主机里面测试

直接输入域名

在这里插入图片描述

测试基于多参数的跳转

在这里插入图片描述

在这里插入图片描述

测试基于不同页面的跳转

在这里插入图片描述

在这里插入图片描述

测试基于指定页面的跳转

在这里插入图片描述

在这里插入图片描述

实验总结

下面,我们来总结一下本次的实验:

1.我们首先要知道rewrite和location的正则表达式的匹配;

2.我们在面对服务起不来的时候,学会查看journalctl -xe,查看自己错那儿了

3.我们要回灵活运用正则表达式和rewrite模块

4.我们要只要rewrite和location的优先级

发布了95 篇原创文章 · 获赞 39 · 访问量 6128

猜你喜欢

转载自blog.csdn.net/double_happy111/article/details/103728828
今日推荐