[nginx] location定位

一、匹配的优先级

Nginx 的 location 匹配的优先级如下 (从高到低)在相同的匹配类型当中,字符串长的会优先匹配

  1. location = 精确匹配
  2. location ^~ 前缀匹配, 例如 location ^~ /hello 等同于 location /hello
  3. location ~ 正则表达式匹配(区分大小写)
  4. location ~* 正则表达式匹配(不区分大小写)
  5. location / 默认通用匹配

注意: 在一个 server 中 location ^~ /hello 和 location /hello 都是指前缀匹配,作用相同。所以这两种匹配方式不能同时出现,只能同时使用其中的一种

二、组织location

2.1 解析配置

ngx_http_core_module.c中的ngx_http_core_location创建 ctx

pctx = cf->ctx;
ctx->main_conf = pctx->main_conf;
ctx->srv_conf = pctx->srv_conf;
ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);

loc_conf[ngx_http_core_module.ctx_index]存储本location解析结果,其中name存放待匹配的字符串,然后以队列元素的方式添加到上一层(server或location nest)的ctx->location,location嵌套则会形成tree结构。
注意,rewrite_module中的if指令也会创建成location,添加到ctx->location,只是name为空

location结构

2.2 调整location

为了现实“匹配的优先级”,需要对location queue做调整。第一步,排序:

  1. 两个比较location中的未命名location(即noname为1,rewrite_module中if指令产生的location)排到后面;
  2. 如果比较的两个location都为未命名location,则维持原次序:用户在配置文件里书写的先后顺序;
  3. 两个比较location中的命名location(即named为1,@前缀)排到后面;
  4. 如果比较的两个location都为命名location,则按字符串大小排序,名称字符序大的排到后面;
  5. 两个比较location中的正则匹配location(即regex字段不为空)排到后面;
  6. 如果比较的两个location都为正则匹配location,则维持原次序:用户在配置文件里书写的先后顺序;
  7. 其他情况,按字符串大小排序。但对于两个location名称相同的情况,如果存在绝对匹配location,则把它放在前面

从队列中摘除后面的未命名location(即noname为1),不用管。再摘除named的location,保存在cscf->named_locations里。然后把regex location摘出来保存到pclcf->regex_locations里。原来的pclcf->locations就只剩下被称为静态(static)的location配置。
执行ngx_http_init_static_location_trees,其中ngx_http_join_exact_locations负责把名称相同的不同location(前缀匹配和绝对匹配)合并成一下节点,inclusive指向前缀location。接着通过ngx_http_create_locations_list创建location list:
location_list

最终调用ngx_http_create_locations_tree,将队列和链表的结构转化成一棵树:
location_tree

三、查找location

ngx_http_core_find_location提供location查找功能:

  1. 执行ngx_http_core_find_static_location,如果查找到绝对匹配location,则定位成功,返回;
  2. 如果前缀匹配location,查找最长子字串,若被“^~”修饰,noregex = 1,则定位成功,返回;
  3. 接着执行正则匹配location,若没有match,则使用第2步中查找到的前缀匹配location
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值