在 nginx server 模块中,location 的定义长被用来匹配一个标准的 URI, 并根据 URI 的不同做出相应的服务方案。
nginx location 匹配的优先级
在 location 中,共有 5 种匹配的模式:
种类 | 写法 |
none | location 中没有指定任何的匹配模式, 会以前缀的方式进行匹配,不会停止搜索,会继续匹配下一个 location 的内容。 |
| location 中需要准确匹配 |
| 会以大小写敏感的方式来匹配 location 中的内容。 |
| 会以大小写不敏感的方式来匹配 location 中的内容。 |
| 如果以非正则的方式,找到了最佳的匹配内容,会停止到这,不再搜索可能存在的正则匹配 。 |
在看完这五种默认的匹配后,可能还是觉得不太容易理解, 下面会以 Nginx 的视角来模拟匹配的过程。
对于每一个请求来说,Nginx 会在配置的多个 location 块中,选取最合适的一个配置块来提供客户端的响应。而为了找到最优的选择,在每一个请求来时,会执行如下的流程:
- Nginx 首先会进行准确的匹配,如果在 location 的配置中找到和
=
后配置相同的内容,就会立即选择这个 location 的配置作为请求的服务端。 - 如果没有以
=
开始的 location 块,Nginx 会开始搜索能够匹配前缀的 location 配置块,并选择匹配最长前缀的 location 进行判断:
- 如果最长匹配的 location 中包含
^~
,Nginx 就会停止搜索,选择这个 location 提供服务。 - 如果最长匹配中 location 不包含
^~
, 也就是 none 的类型,Nginx 会将当前作为临时的参考,继续向下搜索。
- 接着 Nginx 会将 URL 和大小写敏感,大小写不敏感的正则进行匹配。如果匹配成功,就会选择当前的正则 location 配置提供服务。
- 如果没有匹配到任何的正则配置块,就会选择第二步中,作为临时参考保存的配置块进行服务。
简单来说,匹配的优先级就是:=
> ^~
> ~
> ~*
> none
匹配过程具体举例:
假设对 Nginx location 进行了如下的配置:
location = / {
[ configuration A ]
}
location / {
[ configuration B ]
}
location /documents/ {
[ configuration C ]
}
location ^~ /images/ {
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
[ configuration E ]
}
- / 会匹配到 configuration A ,因为
=
是搜索的第一位,也具有最高的优先级。 - /images/1.gif 会匹配到 configuration D 。
首先=
代表的配置块没有匹配成功,会开始进行前缀最长匹配,这时发现 D 满足,且 D 是^~
类型,进而选择 D 。 - /documents/1.jpg 会匹配到 configuration E 。
同样=
代表的配置块没有匹配成功,会开始进行最长前缀匹配,这时发现 E 满足,但 E 并不是^~
类型,因此作为临时方案,继续向下匹配。发现 E 是正则匹配,且能匹配成功,就此结束选择 E 。 - /index.html 会匹配到 configuration B 的配置块。
一样的=
代表的配置块匹配失败,会开始进行最长前缀匹配,这时发现 B 满足,但 B 并不是^~
类型,临时保存,继续匹配。发现并不能找到合适的正则匹配。因此托底方案 B 被选择。
参考