zoukankan      html  css  js  c++  java
  • Nginx:管理HTTP模块的配置项

    参考资料<深入理解Nginx>

    一个nginx.conf的例子

    http {
        mytest_num 1;
        server {
            server_name A;
            listen 80;
            mytest_num 2;
            location /L1 {
                mytest_num 3;
            }
            location /L2 {
                mytest_num 4;
            }
        }  
        server {
            server_name B;
            listen 80;
            location /R1 {
                mytest_num 5;
            }
            location /R2 {
                mytest_num 6;
            }
        }
    }

    核心结构体ngx_http_conf_ctx_t

    typedef struct {
        //指向一个指针数组,数组中的每个成员都是由所有HTTP模块的create_main_conf方法创建的存放全局配置项的结构体
        void **main_conf;
        //指向一个指针数组,数组中的每个成员都是由所有HTTP模块的create_srv_conf方法创建的存放与server相关的结构体
        void **srv_conf;
        //指向一个指针数组,数组中的每个成员都是由所有HTTP模块的create_loc_conf方法创建的存放与location相关的结构体
        void **loc_conf;
    } ngx_http_conf_ctx_t;

    管理main级别下的配置项

    在处理http{}块内的main级别配置项时,对每个HTTP模块,都会调用create_main_conf、create_srv_conf、create_loc_conf方法建立3个结构体。

    它们将以下面所示的数据结构保存起来

    管理server级别下的配置项

    在解析main级别配置项时,如果发现了server{}配置项,就会回调ngx_http_core_server方法解析srv级别的配置项。

    在处理server{}块内的srv级别配置项时,对于每个HTTP模块,都会调用create_srv_conf、create_loc_conf方法建立两个结构体

    (其main_conf指针指向所属的http块下ngx_http_conf_ctx_t结构体的main_conf指针数组)。

    那么HTTP框架是如何管理srv级别的配置项的呢?事实上,在解析main级别的配置项时ngx_http_core_module模块的create_main_conf方法创建了一个很重要的结构体ngx_http_core_main_conf_t:

    typedef struct {
        //存储指针的动态数组,每个指针指向ngx_http_core_srv_conf_t结构体的地址,用于管理srv级别的配置项
        ngx_array_t servers;
        ...
    } ngx_http_core_main_conf_t;

    而在解析srv级别配置项时,ngx_http_core_module模块会调用create_srv_conf方法创建一个ngx_http_core_srv_conf_t结构体:

    typedef struct {
        //指向当前server块所属的ngx_http_conf_ctx_t结构体
        ngx_http_conf_ctx_t *ctx;
        //当前server块的虚拟主机名
        ngx_str_t server_name;
        ...
    } ngx_http_core_srv_conf_t;

    它们的关系如下图所示

    管理location级别下的配置项

    在解析srv级别配置项时,如果发现了location{}配置项,就会回调ngx_http_core_location方法来解析loc级别的配置项

    在处理location{}块内的loc级别的配置项时,对于每个HTTP模块,都会调用create_loc_conf方法来建立一个结构体

    (其main_conf和srv_conf指针都指向所属的server块下ngx_http_conf_ctx_t结构体的main_conf和srv_conf指针数组)。

    那么location级别的配置项时如何管理起来的呢?首先在解析loc级别的配置项时,ngx_http_core_module模块会在create_loc_conf方法中生成ngx_http_core_loc_conf_t结构体:

    struct ngx_http_core_loc_conf_s {
        //location的名称,即nginx.conf中location后的表达式
        ngx_str_t name;
        //指向所属location块内ngx_http_conf_ctx_t结构体中的loc_conf指针数组,它保存着当前location块内所有HTTP模块crete_loc_conf方法产生的结构体指针
        void **loc_conf;
        //将同一个server块内多个表达location块的ngx_http_core_loc_conf_t结构体以双向链表方式组织起来,该locations指向ngx_http_location_queue_t结构体
        ngx_queue_t *locations;
        ...
    };

    可以认为该结构体对应着当前解析的location块,因为它已经拥有足够的信息来表达一个location块:它的loc_conf成员可以引用到个HTTP模块在当前location块中的配置项

    其中ngx_http_location_queue_t结构的定义如下

    typedef struct {
        //queue将作为ngx_queue_t双向链表勇气,从而将ngx_http_location_queue_t结构体连接起来
        ngx_queue_t queue;
        //如果location中的字符串可以景区匹配,exact将指向对应的ngx_http_core_loc_conf_t结构体
        ngx_http_core_loc_conf_t *exact;
        //如果location中的字符串无法精确匹配,inclusive将指向对应的ngx_http_core_conf_t结构体,否则为NULL
        ngx_http_core_loc_conf_t *inclusive;
        //指向location的名称
        ngx_str_t *name;
        ...
    } ngx_http_location_queue_t;

    Nginx将ngx_http_core_loc_conf_t用双向链表组织起来,也就是把location级别的配置项结构体管理起来了。

    (其中所属srv配置块中ngx_http_core_module模块在create_loc_conf方法中生成ngx_http_core_loc_conf_t结构体为链表的首元素),具体结构如下图

    合并不同级别的配置项

    HTTP框架提供了merge_srv_conf方法用于合并main级别和srv级别的server相关的配置项,

    同时,它还提供了merge_loc_conf方法用于合并main级别、srv级别、loc级别的location相关的配置项。

    合并不同级别的配置项的步骤如下:

    1.遍历所有HTTP模块,如果该模块实现了merge_srv_conf方法,则调用该方法来合并main级别和srv级别的server相关的结构体;

    2.遍历所有HTTP模块,如果该模块实现了merge_loc_conf方法,先将main级别和srv级别的location相关的结构体合并,

       然后将srv级别和loc级别的location相关的结构体合并。

  • 相关阅读:
    基本技能训练之线程
    关于UEditor的使用配置(图片上传配置)
    PAT 乙级练习题1002. 写出这个数 (20)
    codeforces 682C Alyona and the Tree DFS
    codeforces 681D Gifts by the List dfs+构造
    codeforces 678E Another Sith Tournament 概率dp
    codeforces 680E Bear and Square Grid 巧妙暴力
    codeforces 678D Iterated Linear Function 矩阵快速幂
    codeforces 679A Bear and Prime 100 交互
    XTUOJ 1248 TC or CF 搜索
  • 原文地址:https://www.cnblogs.com/runnyu/p/4908987.html
Copyright © 2011-2022 走看看