上一篇文章写的nginx的基础安装,以及nginx配置文件的整体结构。这篇文章将会一起来看一下nginx中的一个重要属性location
,location
是放在server里面的,用于匹配访问的域名后的path路径。location
匹配的规则很复杂,内容也是非常多,这里只做简单的介绍。
1. location的匹配规则
1.1 location的三种匹配方式
location的匹配规则有三种,分别是精准匹配、普通匹配和正则匹配。下面对三种匹配做一个说明。
http://blog.itcrud.com/2018/12/12
监听的端口是:80
服务名是:blog.itcrud.com
path:/2018/12/12
精准匹配:根据path做精准匹配,使用的操作符是
=
如下:location = /2018/12/12 { root html/; index index.html; }
普通匹配:请求的
path
和当前的location
指定的值做匹配,location
关键字和规则路径使用空格隔开(也可以用^~
来表示,一般不会这么操作,了解一下),遵从最长匹配路径优先的原则。如下:location /2018 { root html/; index index.html; } location /2018/12 { root html/; index index.html index.htm; } # 两个location都会被命中,但是根据最长匹配原则第二个将会被最终命中。
正则匹配:通过正则表达式的方式来命中,如果命中多个,以最先命中为准,这一点是和普通匹配有所不同。使用的 操作符是
=
。# 正则1 location ~ \.* { root html/; index index.html index.htm; } # 正则2 location ~ \.html$ { root html/; index index.html index.htm; } #当浏览器中输入:http://blog.itcrud.com/regex.html,此时两个正则表达式都是可以命中的,但是由于正则1是在前面,所以会直接作为命中目标,不会再去考虑正则2。
1.2 匹配规则混合使用命中逻辑
在一个server中一般不会只出现一种匹配方式,往往是好几种混合的使用,在多种匹配方式都命中的情况下,到底是以谁为准呢,这里有一个匹配命中的逻辑。看下图:
解释:
- 当直接命中精准匹配的时候,其他的匹配规则就不会再生效,将会按精准规则内的逻辑执行返回。
- 当命中的是普通匹配的时候,命中一个后会直接进入此规则的逻辑。命中多个的话需要根据最长匹配原则来筛选出最终命中的规则。到这里还没有完,命中规则逻辑实现完后,会继续做正则匹配,如果没有匹配到正则规则,就按照普通匹配来做最终返回,如果命中了正则的规则,最终是以正则规则为准。
- 当精准匹配和普通匹配都没有命中时,会进入正则匹配。匹配中给返回,不中也是给返回,但是是错误信息。
2. location下的子元素root
在匹配的时候,根据请求地址中path
到root
到指定的目录下找对应的文件。
示例:
# 请求地址:http://blog.itcrud.com/2018/12/user.html
# location配置:
location /2018 {
root /usr/local/html;
index index.html;
}
请求命中/2018
的的普通匹配规则,请求地址对应的path是/2018/12/user.html
,这个时候会到root
对应目录下找path
对应的文件。最终找的是/usr/local/html/2018/12/user.html
。
3. location下的子元素alias
当配置的是alias
的时候,会将location
匹配的路径舍弃,进入到alias
目录中,按照请求地址的path
找对应的文件,相当于alias
替代了location
配置的匹配地址。
示例:
# 请求地址:http://blog.itcrud.com/2018/12/user.html
# location配置:
location /2018/12 {
alias ^/ /usr/local/html;
index index.html;
}
请求命中规则,请求地址对应的path
是2018/12/user.html
,由于是采用alias
,会将请求地址中/2018/12
替换成/usr/local/html
,最终查找文件的路径是/usr/local/html/user.html
。
4. location下的子元素proxy_pass
proxy_pass
是在使用的时候最经常使用的,上面都是静态文件,这里是将请求转化给代理的服务。
示例:
# 请求地址:http://blog.itcrud.com/2018/user/index.html
# location配置:
location /2018 {
proxy_pass http://127.0.0.1:8081;
}
当请求进来以后,会将请求路由到对应虚拟服务器,请求到服务器的地址是:http://127.0.0.1/2018/user/index.html
。
如果将proxy_pass修改成http://127.0.0.1:8081/
,请求就会不一样,请求到服务器的地址是:http://127.0.0.1//user/index.html
。这个地址是有问题的,IP地址后面会有两个/
。修改正确的写法如下:
# 请求地址:http://blog.itcrud.com/2018/user/index.html
# location配置:这里将"/2018"换成"/2018/"
location /2018/ {
proxy_pass http://127.0.0.1:8081/;# 后面用"/",进行关闭操作
}
# 实际请求地址:http://127.0.0.1/user/index.html
# ↓↓↓↓错误写法
location /2018 { # 这里没有用"/"关闭
proxy_pass http://127.0.0.1:8081/;# 后面用"/",进行关闭操作
}
4.1 proxy反向代理相关参数
proxy_set_header
:通过此参数来指定代理的请求头信息,如:proxy_set_header X-Forwarded-For $remote_addr;#1 proxy_set_header X-Real-IP $remote_addr;#2 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;#3
#1
和#3
有时候会带来坑。nginx默认的配置是#3
。场景:
在外部请求进入nginx后,反向代理进入到对应的服务器中,这个时候服务器需要获取客户端的IP地址,nginx中配置就必须用
#1
指令,如果使用#3
,那么服务器获取的ip永远只是nginx所在机器的IP地址。(如:博客统计访客量)proxy_redirect
:代理重定向,其实和页面重定向是类似的(内部重定向,不改变浏览器请求地址),支持正则表达式的匹配等。proxy_pass http://127.0.0.1:8080; proxy_redirect http://127.0.0.1:8080/server1 http://127.0.0.1:8081/server2;
当进入的请求满足
proxy_redirect
的匹配规则表达式http://127.0.0.1:8080/server1
,就会重定向请求http://127.0.0.1:8081/server2
。proxy_connect_timeout
:向服务器请求连接等待时间,这个时候是在请求获取连接,还没有正式和服务建立连接,最大值不能超过75,此参数的单位是秒。proxy_buffers
:指定缓冲区的大小和数量。如:proxy_buffers 10 8K
,表示缓冲区数量为10,大小是8K。proxy_send_timeout
:服务器数据回传时间,表示请求已经处理结束,响应数据回传等待时间,也就会回传数据经历的时长。proxy_read_timeout
:已经和服务器建立连接,但是一直处于等待处理状态,此参数就是对应等待时间。
还有很多参数就不一一的说明了,一般使用默认的就好,需要设置的也就是主要的几个参数(请求头设置proxy_set_header
、请求重定向设置proxy_redirect
、请求代理设置proxy_pass
)。
5. 总结
简明的总结一下这篇文章的主旨。首先说明一下location
的三种匹配方式以及匹配方式之间的关系。然后就是介绍location
里面的主要的属性alias
、proxy_pass
、root
,当然还有其他重要的属性,篇幅有限,将在下一篇文章来具体说明。