nginx构建static location tree和查找
来源:互联网 发布:网络调试助手的作用 编辑:程序博客网 时间:2024/06/04 18:53
参考地址 : http://blog.chinaunix.net/uid-27767798-id-3759557.html
nginx在处理location的配置的时候,用到了一种三叉排序树,加速了通过request的url和location的映射速度
三叉排序树的形成过程:
pclcf->static_locations = ngx_http_create_locations_tree(cf, locations, 0);
看一下nginx是如何uri和location之间快速做映射的:
static ngx_int_tngx_http_core_find_static_location(ngx_http_request_t *r, ngx_http_location_tree_node_t *node){ u_char *uri; size_t len, n; ngx_int_t rc, rv; len = r->uri.len; //request的请求路径长度 uri = r->uri.data; //request请求的地址 rv = NGX_DECLINED; //默认精准匹配和前缀匹配 匹配不到,需要匹配后面的正则 for ( ;; ) { if (node == NULL) { return rv; } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "test location: "%*s"", node->len, node->name); //n是uri的长度和node name长度的最小值,好比较他们的交集 n = (len <= (size_t) node->len) ? len : node->len; //比较uri和node 的name交集 rc = ngx_filename_cmp(uri, node->name, n); //不得0表示uri和node的name不相等,这时候三叉树就能加速查找的效率,选择node的左节点或者右节点 if (rc != 0) { node = (rc < 0) ? node->left : node->right; continue; //更新节点后重新开始比较匹配 } //如果交集相等,如果uri的长度比node的长度还要长 if (len > (size_t) node->len) { if (node->inclusive) {//如果这个节点是前缀匹配的那种需要递归tree节点,因为tree节点后面的子节点拥有相同的前缀。 //因为前缀已经匹配到了,所以这里先暂且把loc_conf作为target,但是不保证后面的tree节点的子节点是否有和uri完全匹配或者更多前缀匹配的。例如如果uri是/abc,当前node节点是/a,虽然匹配到了location /a,先把/a的location配置作为target,但是有可能在/a的tree节点有/abc的location,所以需要递归tree节点看一下。 r->loc_conf = node->inclusive->loc_conf; //设置成again表示需要递归嵌套location,为什么要嵌套递归呢,因为location的嵌套配置虽然官方不推荐,但是配置的话,父子location需要有相同的前缀。所以需要递归嵌套location rv = NGX_AGAIN; node = node->tree; //node重新变为tree节点 uri += n; len -= n; continue; } /* exact only */ //对于精确匹配的location不会放在公共前缀节点的tree节点中,会单拉出来一个node和前缀节点平行。也就是说对于精确匹配 =/abcd 和前缀匹配的/abc两个location配置,=/abcd不会是/abc节点的tree节点。=/abcd 只能是/abc的right节点 node = node->right; continue; } if (len == (size_t) node->len) { //如果是uri和node的name是完全相等的 if (node->exact) { //如果是精确匹配,那么就是直接返回ok了 r->loc_conf = node->exact->loc_conf; return NGX_OK; } else { //如果还是前缀模式的location,那么需要递归嵌套location了,需要提前设置loc_conf,如果嵌套有匹配的再覆盖 r->loc_conf = node->inclusive->loc_conf; return NGX_AGAIN; } } /* len < node->len */ if (len + 1 == (size_t) node->len && node->auto_redirect) { r->loc_conf = (node->exact) ? node->exact->loc_conf: node->inclusive->loc_conf; rv = NGX_DONE; } //如果前缀相等,uri的长度比node的长度还要小,比如node的name是/abc ,uri是/ab,这种情况是/abc 一定是精确匹配,因为如果是前缀匹配那么/abc 肯定会再/ab的tree 指针里面。 node = node->left; }
总结:
static location tree大大优化了精准匹配和前缀匹配的location的查找过程,线性递归查找效率低下,三叉树的左节点代表当前比node节点的name小的节点,右节点代表比当前node节点name大的节点,tree节点表示拥有相同前缀的节点。
问题:
关于request的请求过程
0 0
- nginx构建static location tree和查找
- nginx location tree
- nginx rewirte 和 location
- nginx location的管理以及查找
- nginx location的管理以及查找
- nginx location的管理以及查找
- Nginx location的管理以及查找
- Nginx location 和 rewrite retry
- Nginx location和正则归纳
- nginx--- location 和 rewrite 顺序
- Nginx location
- nginx Location
- nginx location
- nginx location
- location nginx
- nginx location
- Nginx的location匹配规则和全局变量
- Nginx的location和rewrite配置语法
- 常用的jar包(三)
- tensorflow 几个android demo源码环境搭建
- swoole+websocket+html5实现的简易版直播功能
- android studio使用Aidl跨进程调用服务
- Python Selenium实现自动登录163邮箱
- nginx构建static location tree和查找
- 程序执行时间
- 工作流网(workflow net)
- 文章标题
- openssl证书命令行
- JavaWeb实现文件上传下载功能实例解析
- css3原生变量var
- openstack问题记录
- ng-grid的server端排序/列筛选/翻页/loading