nginx之location配置
[TOC]
location理论基础
语法介绍
语法
location [ = | ~ | ~* | ^~ ] uri { ... }
路径匹配
以何开头 | 匹配功能 |
---|---|
= | 表示精确匹配,只有请求的URL完全相等才会被匹配,匹配成功则立即停止搜索 |
~ | 表示区分大小写的正则匹配 |
~* | 表示不区分大小写的正则匹配 |
^~ | 表示url以某个字符串开头,不是正则匹配,属于前缀字符串 |
/ | 表示通用匹配,如果没有其它匹配,任何请求都会匹配到,属于前缀字符串 |
测试过程
- = 表示精确匹配
#.测试配置
location = /test {
#.精确匹配
return 200 "hello";
}
#.测试结果
curl http://127.0.0.1/test ok
curl http://127.0.0.1/test/ not ok
curl http://127.0.0.1/test2 not ok
curl http://127.0.0.1/test/2 not ok
- ~ 表示区分大小写的正则匹配
#.测试配置
location ~ ^/test$ {
#.区分大小写
return 200 "hello";
}
#.测试结果
curl http://127.0.0.1/test ok
curl http://127.0.0.1/Test not ok
curl http://127.0.0.1/test/ not ok
curl http://127.0.0.1/test2 not ok
- ~* 表示不区分大小写的正则匹配
#.测试配置
location ~* ^/test$ {
#.不区分大小写
return 200 "hello";
}
#.测试结果
curl http://127.0.0.1/test ok
curl http://127.0.0.1/Test ok
curl http://127.0.0.1/test/ not ok
curl http://127.0.0.1/test2 not ok
- ^~ 表示url以某个字符串开头
#.测试配置
location ^~ ^/images/ {
#.url以某个字符串开头
return 200 "hello";
}
#.测试结果
curl http://127.0.0.1/images/1.jpg ok
- / 表示通用匹配
#.测试配置1
location / {
#.通用匹配
return 200 "hello";
}
#.测试结果1
curl http://127.0.0.1/index.html ok
#.测试配置2
location /test {
#.通用匹配
return 200 "hello";
}
#.测试结果2
curl http://127.0.0.1/test ok
curl http://127.0.0.1/test2 ok
curl http://127.0.0.1/test/ ok
curl http://127.0.0.1/Test not ok
匹配顺序
Location的定义分为两种
- 前缀字符串(prefix string),包括
完整路径
和部分起始路径
- 正则表达式(regular expression),具体为前面带
~*
和~
修饰符的
在顺序上
- 前缀字符串顺序不重要,按照匹配长度来确定
- 正则表达式则按照定义顺序,先匹配到则先返回
在优先级上
- 精确
=
> 完整路径 > 前缀^~
> 正则~,~*
> 部分起始路径 > 通用/
测试过程
- 场景1:如下配置,虽然
/doc
也能匹配到,但在顺序上,前缀字符串顺序不重要,按照匹配长度来确定
#.测试配置
server {
location /doc {
return 200 "ResultA";
}
location /docu {
return 200 "ResultB";
}
}
#.测试结果
curl http://127.0.0.1/document 匹配结果 ResultB
- 场景2:如下配置,虽然
~ ^/docu
也能匹配到,但 正则表达式则按照定义顺序,先匹配到则先返回
#.测试配置
server {
location ~ ^/doc {
return 200 "ResultA";
}
location ~ ^/docu {
return 200 "ResultB";
}
}
#.测试结果
curl http://127.0.0.1/document 匹配结果 ResultA
- 场景3:如下配置,虽然正则表达式
~ ^/docu
也能匹配到,但 前缀字符串^~
的优先级更高
#.测试配置
server {
location ^~ /doc {
# 前缀字符串 ^~ 表示 url 以某个字符串开头
return 200 "ResultA";
}
location ~ ^/docu {
# 正则表达式 ~ 表示区分大小写
return 200 "ResultB";
}
}
#.测试结果
curl http://127.0.0.1/document 匹配结果 ResultA
- 场景4:如下配置,虽然前缀字符串
/document
也能匹配到,但 正则表达式 ~ 的优先级更高
#.测试配置
server {
location /document {
# 前缀字符串 / 表示通用匹配
return 200 "ResultA";
}
location ~ ^/docu {
# 正则表达式 ~ 表示区分大小写
return 200 "ResultB";
}
}
#.测试结果
curl http://127.0.0.1/document 匹配结果 ResultB
root 与 alias 的区别
配置如下2个location
location ^~ /tea/ {
root /data/html;
}
location ^~ /sta/ {
alias /data/static;
}
- 访问
http://test.com/tea/tea1.html
>> /data/html/tea/tea1.html - 访问
http://test.com/sta/sta1.html
>> /data/static/sta1.html
两者的区别
- root 实际访问文件路径会拼接 root + location
- alias 实际访问文件路径不会拼接location中的路径
server 和 location 中的 root
- server 和 location 中都可以使用 root,如下所示,哪个优先级更高呢?
server {
listen 80;
server_name localhost;
root /data/app/;
location / {
root /data/web/;
index index.html;
}
}
- 简单的来说,就是 就近原则,如果 location 中能匹配到,就是用 location 中的 root 配置,忽略 server 中的 root
- 当 location 中匹配不到的时候,则使用 server 中的 root 配置。
实战配置
注意配置表达式重复
- 如下配置,若将前缀字符串中的
location /api
改成location /api/
则会报错,nginx: [emerg] duplicate location "/api/"
server {
listen 80;
location ^~ /api/ {
# 正则表达式,匹配任何以 /api/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条
return 200 "ResultA";
}
location /api {
# 前缀字符串,匹配以 /api 开头的地址,优先级没有上面的正则表达式高
return 200 "ResultB";
}
}
通过location实现流量分流
- 场景:假设某网站的请求过大导致卡顿,需要对2个流量较大的子目录做分流,需求如下:
用户访问 https://xxx.com 则流量转到 节点1或节点2
用户访问 https://xxx.com/match 则流量转到 http://节点3:8187/match
用户访问 https://xxx.com/images 则流量转到 https://节点4:443/images
- 为了达到上述效果,可以配置如下:
http {
#.其他省略
upstream myservers {
server 10.30.3.201:443 max_fails=5 fail_timeout=300s weight=10;
server 10.30.3.202:443 max_fails=5 fail_timeout=300s weight=10;
}
server {
listen 443 ssl;
server_name xxx.com;
ssl_certificate /usr/local/nginx/conf/ssl/xxx.com.pem;
ssl_certificate_key /usr/local/nginx/conf/ssl/xxx.com.key;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / { #.首页
index index.html index.htm index.php;
proxy_timeout 300s;
proxy_pass https://myservers;
#.供下面参考
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Connection "";
proxy_http_version 1.1;
}
location ^~ /match { #.match站点
proxy_timeout 300s;
proxy_pass http://10.30.3.203:8187/match/;
#.其他参考上面
}
location ^~ /images { #.images站点
proxy_timeout 300s;
proxy_pass https://10.30.3.204:443/images/;
#.其他参考上面
}
}
}