• nginx开发_配置项


    nginx开发笔记_配置项

    模块的配置项即nginx.conf中的指令,HTTP模块指令可以分为三个级别:

    • main级,直接写在http{}块中的指令
    • server级,写在server{}块中的指令
    • location级,写在location{}块中的指令

    配置项定义模板

    在自定义模块中使用配置项,需要配置ngx_module_t的commands属性以及ctx属性,并需要定义一个结构体用于存放配置信息。

    常用的模板如下:

    /* 存放配置信息的自定义结构体 */
    typedef struct
    {
        ngx_flag_t        my_flag;
    } ngx_http_mytest_conf_t;
    
    /* 模块声明 */
    ngx_module_t  ngx_http_mytest_module =
    {
        NGX_MODULE_V1,
        &ngx_http_mytest_module_ctx,           /* module context */
        ngx_http_mytest_commands,              /* module directives */
        NGX_HTTP_MODULE,                       /* module type */
        NULL,                                  /* init master */
        NULL,                                  /* init module */
        NULL,                                  /* init process */
        NULL,                                  /* init thread */
        NULL,                                  /* exit thread */
        NULL,                                  /* exit process */
        NULL,                                  /* exit master */
        NGX_MODULE_V1_PADDING
    };
    
    /* 配置项处理回调函数注册 */
    static ngx_http_module_t  ngx_http_mytest_module_ctx =
    {
        ngx_http_mytest_pre_conf,          /* preconfiguration */
        ngx_http_mytest_post_conf,         /* postconfiguration */
        ngx_http_mytest_create_main_conf,  /* create main configuration */
        ngx_http_mytest_init_main_conf,    /* init main configuration */
        ngx_http_mytest_create_srv_conf,   /* create server configuration */
        ngx_http_mytest_merge_srv_conf,    /* merge server configuration */
        ngx_http_mytest_create_loc_conf,   /* create location configuration */
        ngx_http_mytest_merge_loc_conf     /* merge location configuration */
    };
    
    /* 自定义的配置项 */
    static ngx_command_t  ngx_http_mytest_commands[] =
    {
        {
            ngx_string("test_flag"),
            NGX_HTTP_LOC_CONF | NGX_CONF_FLAG,
            ngx_conf_set_flag_slot,
            NGX_HTTP_LOC_CONF_OFFSET,
            offsetof(ngx_http_mytest_conf_t, my_flag),
            NULL
        },
        ngx_null_command
    };
    

    配置项信息

    配置项信息通过ngx_command_t类型指定

    struct ngx_command_s {
        ngx_str_t             name;
        ngx_uint_t            type;
        char               *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
        ngx_uint_t            conf;
        ngx_uint_t            offset;
        void                 *post;
    };
    
    • name 命令名称

    • type 设置配置项允许在哪些配置块中使用、配置项携带的参数个数、参数形式信息。具体可以参考ngx_conf_file.h和<深入理解Nginx 第2版>P116 表4-1。常用选项如下

      /*
       *        AAAA  number of arguments
       *      FF      command flags
       *    TT        command type, i.e. HTTP "location" or "server" command
       */
      #define NGX_HTTP_MAIN_CONF        0x02000000
      #define NGX_HTTP_SRV_CONF         0x04000000
      #define NGX_HTTP_LOC_CONF         0x08000000
    
      #define NGX_CONF_BLOCK       0x00000100
      #define NGX_CONF_FLAG        0x00000200
      #define NGX_CONF_ANY         0x00000400
      #define NGX_CONF_1MORE       0x00000800
      #define NGX_CONF_2MORE       0x00001000
    
      #define NGX_CONF_NOARGS      0x00000001
      #define NGX_CONF_TAKE1       0x00000002
      #define NGX_CONF_TAKE2       0x00000004
      #define NGX_CONF_TAKE3       0x00000008
      #define NGX_CONF_TAKE4       0x00000010
    
    • set属性指定配置项解析函数,ngx提供了12个常用的解析函数如下所示,解析的格式可以参考<深入理解Nginx 第2版>P118 表4-2 。也可以实现自定义的解析函数。
    char *ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
    char *ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
    char *ngx_conf_set_str_array_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
    char *ngx_conf_set_keyval_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
    char *ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
    char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
    char *ngx_conf_set_off_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
    char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
    char *ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
    char *ngx_conf_set_bufs_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
    char *ngx_conf_set_enum_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
    char *ngx_conf_set_bitmask_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
    
    • conf 用于指定配置项的偏移,与后文的create_xxx_conf回调函数有关。例如配置项是通过create_loc_conf函数创建的,此处的配置就应该为NGX_HTTP_LOC_CONF_OFFSET。

      可选参数如下:

    #define NGX_HTTP_MAIN_CONF_OFFSET  offsetof(ngx_http_conf_ctx_t, main_conf)
    #define NGX_HTTP_SRV_CONF_OFFSET   offsetof(ngx_http_conf_ctx_t, srv_conf)
    #define NGX_HTTP_LOC_CONF_OFFSET   offsetof(ngx_http_conf_ctx_t, loc_conf)
    
    • offset 用于指定配置项关联的结构体字段的偏移,一般使用offsetof宏设置。
    • post指针,传递给set函数的参数,具体含义根据set函数而定。

    配置项创建与合并

    配置项创建与合并主要通过ngx_http_module_t的回调函数实现。

    typedef struct {
        ngx_int_t   (*preconfiguration)(ngx_conf_t *cf);
        ngx_int_t   (*postconfiguration)(ngx_conf_t *cf);
        void       *(*create_main_conf)(ngx_conf_t *cf);
        char       *(*init_main_conf)(ngx_conf_t *cf, void *conf);
        void       *(*create_srv_conf)(ngx_conf_t *cf);
        char       *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf);
        void       *(*create_loc_conf)(ngx_conf_t *cf);
        char       *(*merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf);
    } ngx_http_module_t;
    

    其中preconfigurationpostconfiguration相对好理解,在配置项创建整体前后分别回调。

    create_main_confcreate_srv_confcreate_loc_conf三个函数的回调次数与nginx中具体的配置有关。以如下配置为例:

    http {
        test_str SUPERMAN;
        server {
            server_name HOST1;
            location /HOST1_loc1 {
                test_str    loc1_BANANA;
            }
            location /HOST1_loc2 {
            }
        }
        server {
            server_name HOST2;
            test_str CAR;
            location /index {
                test_str FOCUS;
            }
            location /test {
                test_str    PLANE;
            }
            location = /50x.html {
            }
        }
    }
    

    HTTP模块遇到http{}配置块时将调用create_main_conf、create_srv_conf、create_loc_conf三个函数,遇到server{}块时将调用create_srv_conf、create_loc_con两个函数、遇到location{}块时将调用create_loc_con函数。所以以上配置create_main_conf将被调用1次,create_srv_conf被调用3次,create_loc_conf被调用8次。一般HTTP模块都仅使用loc级的配置。

    create_xxx_conf函数中一般的内容为创建自定义配置结构体,并设置初始值。常见如下:

    static void *
    ngx_http_sub_create_conf(ngx_conf_t *cf)
    {
        ngx_http_sub_loc_conf_t  *slcf;
    
        slcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_sub_loc_conf_t));
        if (slcf == NULL) {
            return NULL;
        }
    
        slcf->once = NGX_CONF_UNSET;
        slcf->last_modified = NGX_CONF_UNSET;
    
        return slcf;
    }
    

    上文中提到在http{}和server{}中都会调用create_loc_conf,那么在具体处理请求时将使用那个级别的的配置,则由init_main_conf、merge_srv_conf、merge_loc_conf回调函数决定。已merge_loc_conf为例

    (merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf);
    

    prev指针为父级配置的结构体,conf为子级配置的结构体。一个常用的思路时:如果子级没有配置则复用父级的,常用方式如下:

    static char *
    ngx_http_mytest_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
    {
        ngx_http_mytest_conf_t *prev = (ngx_http_mytest_conf_t *)parent;
        ngx_http_mytest_conf_t *conf = (ngx_http_mytest_conf_t *)child;
    
        ngx_conf_merge_str_value(conf->my_str, prev->my_str, "defaultstr");
        return NGX_CONF_OK;
    }
    

    ngx_conf_merge_str_value是合并str类型的宏,其他宏还包括

    #define ngx_conf_merge_value(conf, prev, default)
    #define ngx_conf_merge_ptr_value(conf, prev, default)
    #define ngx_conf_merge_uint_value(conf, prev, default)
    #define ngx_conf_merge_msec_value(conf, prev, default)
    #define ngx_conf_merge_sec_value(conf, prev, default)
    #define ngx_conf_merge_size_value(conf, prev, default)
    #define ngx_conf_merge_off_value(conf, prev, default)
    #define ngx_conf_merge_str_value(conf, prev, default)
    #define ngx_conf_merge_bufs_value(conf, prev, default_num, default_size)
    #define ngx_conf_merge_bitmask_value(conf, prev, default)
    

    注意merge_loc_conf与create_loc_conf类似,在三个级别中会被调用多次,以上文的配置示例来说,merge_loc_conf会被调用7次,比create_loc_conf少1次,因为http{}不需要merge。

    【此处的设计逻辑个人还没想理解十分明白,初步理解分三层配置用于一个模块中http{}srv{}loc{}需要定义使用不同conf_t结构体的场景,反复调用create函数是为了实现可以选择是否复用(merge)父级的功能。】

    配置项获取

    一般可以通过ngx_http_request_t *r变量或者ngx_conf_t *cf变量获取配置项的内容。常用的接口如下

    #define ngx_http_get_module_main_conf(r, module)
    #define ngx_http_get_module_srv_conf(r, module)
    #define ngx_http_get_module_loc_conf(r, module)
    
    #define ngx_http_conf_get_module_main_conf(cf, module)
    #define ngx_http_conf_get_module_srv_conf(cf, module)
    #define ngx_http_conf_get_module_loc_conf(cf, module)
    

    示例代码如下:

    static ngx_int_t
    ngx_http_addition_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
    {
        ...
        ngx_http_addition_conf_t  *conf;
        ...
        conf = ngx_http_get_module_loc_conf(r, ngx_http_addition_filter_module);
    }
    
  • 相关阅读:
    JVM的学习5_____垃圾回收:分代收集算法
    JVM的学习4____GC的作用和垃圾的标记
    JVM的学习3_____逃逸分析与栈上分配
    JVM的学习2____对象实例的内存分配原理
    JVM的学习1_____内存模型
    SpringMVC的学习____6.JSON 和Ajax
    两种方法关联控制器和DOM
    img的src,a的href使用{{}}设置属性不能生效
    ng之{{value}}顺序
    ng之ng-app指令
  • 原文地址:https://www.cnblogs.com/atskyline/p/7853153.html
Copyright © 2020-2023  润新知