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的优先级