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相关的结构体合并。

  • 相关阅读:
    小程序升级实时音视频录制及播放能力,开放 Wi-Fi、NFC(HCE) 等硬件连接功能
    12306网站将新增微信通知方式
    QQ-AR助人教版小学英语“动”起来
    【福利】公众平台全面开放原创功能
    12月微信的新规来了
    微信公众平台原创声明和留言功能面向微信认证帐号公测
    微信公众平台支持开通微信小店小程序了
    腾讯2017年第三季度财报:微信广告收入大幅增长
    2017微信数据报告 截至9月日登录用户超9亿日发送消息380亿次
    iOS版微信6.5.21发布 适配iPhone X
  • 原文地址:https://www.cnblogs.com/runnyu/p/4908987.html
Copyright © 2011-2022 走看看