nginx(九)find_config阶段的location指令

 一   location

server块中的'rewrite'阶段执行完,进入'find_config'阶段,进行'location'匹配

①   location

细节点: '$uri[不携带查询参数的path]'与'location'进行匹配

特点: 根据'用户请求的URI'来匹配'location',匹配'success'则执行对应的'configure'配置块

②  location中的符号

++++++++++++ '几种符号的理解'  ++++++++++++

(1) 第'1'阶段:'前缀(prefix)'匹配  --> 'the longest prefix mactch'

'=': 表示'精准exact'匹配,必须'完全一致才会停止'匹配其它的location

'^~':也是'前缀'匹配,'no regex';但是只有是'最长前缀匹配'时,才会'停止匹配'其它的location

'空':表示一般'prefix前缀'匹配

(2) 第'2'阶段:'正则(regular)'匹配

'~': 区分'大小写'

'~*':不区分大小写

备注: 不能在location 'regular'中使用'!'

(3) '命名@'匹配

应用场景:'error_page'、'try_files'指令、'X-Accel-Redirect'响应头可以使用

关注点:什么是'prefix string'?、什么是'regular expression'? --> "对应哪些修饰符"?

location 匹配规则详解

1.location 的匹配'查找'顺序是"先匹配普通,再匹配正则"

'一句话'总结:

  1) 正则 location 匹配'让步'普通 location 的严格精确匹配结果

  2) 但'覆盖'普通 location 的'最大'前缀匹配结果

③  最长前缀匹配的底层逻辑

nginx会在'启动'过程中,将'server{}内'的所有location'基于前缀'的包含关系,建立一颗'多叉树'

++++++++++++ "假定这些无modifier的前缀location" ++++++++++++

location /test             {root html;}
location /res              {root html/res;}
location /res/img          {root html/res/img;}
location /res/video        {root html/res/video;}
location /                 {root html/res;}
location /resource/js      {root html/res;}
location /resource/image   {root html/res;}
location /his              {root html/res;}
location /his/20           {root html/res;}
location /his/2020         {root html/res;}
location /his/20/02        {root html/res;}
location = /50x.html       {}

1)如下'12'个location将会构造出1颗'4层的静态树'

2)其中'子树'中的所有location,都是比'父结节更长'的前缀location

3)在'同一层'的结点中,它们互不相属,但却是'基于字母表'有序的

++++++++++++ "顺序排列问题"  ++++++++++++

图片链接来源

 

nginx源码分析location

④  如何匹配正则表达式location

说明: 遇到'前缀匹配无法覆盖'的url时,可以使用'正则表达式'匹配请求

1)多个正则表达式location之间的'匹配次序'

2) 按照它们在server{}块中'出现'的位置,'依次'匹配,直接使用'最先命中'的location即可

2)注意:当'上方'的正则表达式匹配'范围过大'时,下方的正则表达式location可能永远也'无法命中'

⑤  正则表达式与前缀location同时出现时

1)= 前缀精确匹配 

1)在执行'前缀'匹配时,如果URL与location'完全相等'

2)那么nginx'不会再检索'子树寻找更长的'前缀'匹配,但还会执行'正则'表达式匹配

3)如果你希望'URL完全相等'后,'不必'再匹配正则表达式location,那么可以在location前增加'='号

4)应用场景:如果某些页面'访问频率'非常高,你应该用'='号加快location的'匹配'速度

 2) ^~

注意:只有'最长匹配上'携带'^~'符号,才能够'跳过'正则表达式

+++++++++++++ "解读"  +++++++++++++

1)虽然这个请求'同时命中了3个'location

2)但'2个前缀'location中

   [1]、/redirect1虽然带有'^~'符号,可惜它却'不是最长'的前缀匹配

   [2]、而/redirect11虽然是'最长'前缀,但又'不能阻止'正则表达式

3)最终'/redirect1(\d)?'匹配上'url'

 

⑥  location匹配顺序

++++++++++++ '优先级问题'  ++++++++++++

注意:不是按照'nginx.conf'配置文件的'location'先后顺序匹配的

(1) 先匹配所有的'prefix location'

(2) 首先'='前缀精准匹配,匹配成功立即'处理并且停止'location继续匹配

(3) 如果'没有'精准匹配,会进行'^~前缀匹配',^~匹配上也会立即'处理并且停止'location继续匹配

(4) 如果'='和'^~'都没有匹配上,暂存'最长'前缀匹配,开始进行'正则匹配'

(5) 如果'正则'匹配,则使用'正则匹配上'的,否则'使用之前暂存'的"最长前缀字符的location"

细节点: 不考虑'~'和'~*'正则的优先级,'正则'完全按照'配置'文件的顺序

++++++++++++ 'location / 兜底原因 '  ++++++++++++

1) 为了'避免'第1步中就'没有找到'能匹配上的前缀location,导致基于'root'直接返回'404'

2) 通常会在'末尾'添加'location / {}'兜底,它可以匹配'任意'URL,相当于'switch default'

 ⑦  官方案例

⑧  @name 定义命名location

1: '修饰符@'用于定义一个'内部' location 块,该块'不能'被外部 client '直接'访问

2: 只能被 nginx '内部配置指令'所访问:比如 'try_files' 或者'error_page'

备注:'internal'也是'同样'的效果

+++++++++++  'error_page'中 '@' 使用  +++++++++++  

location 的'内部跳转'匹配符号'@':

location /index/ {
  error_page 404 @index_error;
}

location @index_error {
  return 404 'ok\n';
}

解读:以 /index/ 开头的请求,如果'现状态码是 404',则会匹配到 @index_error 这条'规则'上

+++++++++++  'try_files'中 '@' 使用  +++++++++++ 

location / {
    try_files $uri $uri/ @custom
}

location @custom {
    # ...do something
}

⑨  location嵌套 

说明: 了解'有这种用法'即可,下面进行了'详细'的解读

⑩  加不加/问题

纠正: '/user'和'/user/'有区别的 --> /user会'返回301'和 'user/ 重定向'

 

二  location nested location

①  存在父子关系的location条件限制

location快速查询

+++++++++++++++  location共分为'四'种  +++++++++++++++

1) exact_match:"="类型,'精准'匹配;

2) noregx:"^~[特殊]"或""类型,'非正则'的特殊'前缀'匹配;

3) regex:"[!]~[*]",正则匹配;

4) named:"@"类型,'内部'跳转匹配,也是'精确匹配';

+++++++++++++++ 对于存在'父子关系'的location  +++++++++++++++

1) 父只能是'noregex'或'regex'类型;

2) 子location'不能'是named类型;

3) 子的name'不能'包含父

+++++++++++ "一般正则嵌套的风格 [正常的]"  +++++++++++

server {
  location /images {
    location /images/icons {
      # ...
    }
    
    location /images/photos {
      # ...
    }
  }
}

②  动作指令和值指令

1) 值指令:存储'配置项的值[静态]',是用来'配置'某一个配置项的,可以'继承|覆盖'

eg: root、add_header、access_log、index等

2) 动作类指令:指定行为'动作action',往往表示接下来'要做'一件事情,不可以'合并被继承'

eg: rewrite、proxy_pass、try_files、return

3) 指令分类:Normal、Array、Action、Action、try_files

 Normal指令    - 每个上下文一个值,例如:"root"或"index"
 Array指令     - 每个上下文可以有,'多个'值,例如:"access_log"或"add_header"
 Action指令    - 不只是配置的东西,例如:"rewrite"
 try_files指令 - 'server'或'location'上下文不同

4) 目的: 'location嵌套location',一些'继承和覆盖'问题,基本同之前'context'

  备注:'子location'作用域名小于'父'location

Nginx 配置继承模型

Standard Type Directives Array Type Directives Command Type Directives

③  location嵌套改变find_location

location in location的优先级    原始嵌套解读

1) Exact string  'exact matches' location = /foo

2) The 'longest' of any location '^~' ... matches

3) The 'first (exact prefix |regex match)' that \
  is nested within the single longest 'matching prefix' match!

备注:原文描述的结论'不准确',这里做了'修改'

4) The first 'other regex' match location '~' regex

5) The 'longest prefix match' location /foo

注意事项:子location要包含在父location中

++++++++++ "案例讲解" ++++++++++

'难点'理解:

  1) 如果对应'location'嵌套的是'prefix location',并且是'longest prefix match'

  2) 重新按照'=、^~、regular'顺序在'子location'中寻找

  不同点:在嵌套中'^~'是最长'前缀'匹配,会停止'该level的regular',但是不会停止'父regular'

grep -En 'test location|using configuration' /var/log/nginx/error.log '看过程'

案例1: '/wzj'请求

第'1'阶段:'/wzj' 是'最长'的前缀匹配,发现是'嵌套',然后'=和^~'都不匹配,则使用嵌套'regular'

案例2: '/wzj11'请求

第'1'阶段: '/wzj1 [最长的前缀匹配]',但不是'=、^~',不能停止'regular'

第'2'阶段: 使用 '~ wzj'

案例3: '/wzj22'请求

第'1'阶段: '/wzj [最长的前缀匹配]',查看该嵌套的'= /wzj22',则'停止'后续的location查找

思考: '/wzj222'呢? --> '~ /wzj(.*)' --> nested location regular 222 ok!

案例4: '/wzj3'请求

细节点: 

  1) 第'1'阶段: '/wzj [最长的前缀匹配]',查看该嵌套的'^~ /wzj3 [最长前缀匹配]'

  2) 'nested location'中,'^~ /wzj3'使'该level'下的正则'~ ^/wzj(.*)'停止

  3) 但是没有作为'最终的'location,而是'跳出嵌套location',继续寻找父regular '~ /wzj'

案例5: '/wzj33'请求  --> "同上"

L1 L2 L3   proxy_set_header

nginx nested location add_header

三   相关参考

location最佳实践参考

深入理解location匹配规则

一文理清nginx中的location配置

location讲解最好的博客

URL是如何关联location配置块的

辉神URL是如何关联location配置块的

重定向和请求转发的区别 

 location匹配小结 

更详细的正则匹配

nginx 的location详细理解

nginx的正则表达

nginx 下 location 某个文件夹下某类文件

Nginx location 匹配规则

题外话: 

  1) location是基于'$uri'进行find_location匹配的

  2) '$uri'是'decode解码'后的,'不带'查询参数;'$request_uri'是'原始 url encode的'带参

 +++++++++++++  "动静态分离"  +++++++++++++

 1)如何识别'静态'页面,让'web服务器(nginx)'处理      

  常用: '/static'或者'\.(?:html|js|jpg)',通过'root指令'
 
 2)如何识别'动态'页面,让'应用服务器(tomcat、django)' 

 常见: 'proxy_pass、grpc_pass、fastcgi_pass'

其它: rewrite ^/pets/rabbits/?$ /pets/rabbits.html last;  --> '解决带不带/'的问题
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值