[nginx] location定位

来源:互联网 发布:武工队后勤部淘宝 编辑:程序博客网 时间:2024/05/18 22:41
  • nginx document
  • nginx配置:location配置方法及实例详解
  • 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 0