Nginx http的初始化(一)

其实经过前面文章的分析,我们已经知道在Nginx启动的时候会先进行core类型模块的处理。在Nginx的每一部分都会有一个core类型的模块与之对应,在解析配置文件的时候,这些core类型的模块便是这些他们所代表的部分的入口。例如event部分,ngx_events_module模块就是一个core类型的模块,因而我们可以看到event部分的初始化其实是从ngx_events_module模块的命令events的set回调函数开始的。

另外在每一部分都有一个比较重要的核心模块,例如event部分有ngx_event_core_module模块,其虽然只是一个event类型的模块,但是其却处理了event部分的大多数命令,而且它的配置结构也会保存很多十分重要的信息,例如ngx_event_core_module的配置结构ngx_event_conf_t就保存了event是否使用互斥信号,具体使用哪一个时间模块的等信息。其实要分析nginx每一部分就应该从这两个模块开始。

好了,那么就按照上面的说法来分析http部分吧,先找到core类型的模块,它是ngx_http_module模块,其定义如下:

static ngx_command_t  ngx_http_commands[] = {
    { ngx_string("http"),
      NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
      ngx_http_block,
      0,
      0,
      NULL },

      ngx_null_command
};

static ngx_core_module_t  ngx_http_module_ctx = {
    ngx_string("http"),
    NULL,
    NULL
};
ngx_module_t  ngx_http_module = {
    NGX_MODULE_V1,
    &ngx_http_module_ctx,                  /* module context */
    ngx_http_commands,                     /* module directives */
    NGX_CORE_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
};
我们可以看到 ngx_http_module模块只有一个命令,那就是http,其的set回调函数式ngx_http_block函数。

(嗯,这个地方要插入一个话题,我们知道每种类型的模块的配置结构并不是保存在模块内部的,我们可以看到全局cycle变量有一个域是ctx,它用来保存“所有”模块的配置结构上下文,这里用引号是有道理的。其实ctx只是保存了每一部分core类型的模块的配置结构,然后再用core类型模块的配置结构来保存其所在部分的其余具体模块的配置结构,然后其余具体模块想要获取其的配置,就得先找到代表它的core类型的模块,进而才能找到其的配置结构。也就是说模块的配置结构的保存其实是按照层次来进行的,嗯,这个部分以后干脆写一篇文章来说明吧,这个比较关键,如果不搞透彻的话,对于理解代码会带来很大的问题。)

好了,说了太多的废话,接下来回归http。这里我们来看看http部分是如何来保存其具体模块的配置结构的吧。嗯,http部分还是比较奇葩的。这里要看一下ngx_http_conf_ctx_t这个结构:

//http模块的配置结构的定义
typedef struct {
    void        **main_conf;  //所有http模块的main config数组(可以把它看成指针的数组)
    void        **srv_conf;   //所有http模块的srv config数组
    void        **loc_conf;   //所有http模块的 loc config数组
} ngx_http_conf_ctx_t;
在全局cycle变量的ctx域的 ngx_http_module模块index处将会保存这么一个结构,用它来索引其余所有http类型模块的配置结构。嗯,够奇葩的,也就是说每一个http模块最多有可能有三种配置结构了。

好了。接下开始http部分的核心模块了,它是ngx_http_core_module模块,我们先看一下它的定义:

static ngx_http_module_t  ngx_http_core_module_ctx = {
    ngx_http_core_preconfiguration,        /* preconfiguration */
    NULL,                                  /* postconfiguration */

    ngx_http_core_create_main_conf,        /* create main configuration */
    ngx_http_core_init_main_conf,          /* init main configuration */

    ngx_http_core_create_srv_conf,         /* create server configuration */
    ngx_http_core_merge_srv_conf,          /* merge server configuration */

    ngx_http_core_create_loc_conf,         /* create location configuration */
    ngx_http_core_merge_loc_conf           /* merge location configuration */
};


ngx_module_t  ngx_http_core_module = {
    NGX_MODULE_V1,
    &ngx_http_core_module_ctx,             /* module context */
    ngx_http_core_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
};
由于其的命令太多了,这里就不贴出来了。只能说那些重要的命令都被这个模块包含了。然后我们在来看看它的配置结构吧,因为其配置结构将会保存http部分许多重要的配置信息。(这货居然三种类型的配置结构都有)我们首先来看它的main_conf(这个很重要):
typedef struct {
	 /** 
     * 存储所有的ngx_http_core_srv_conf_t,元素的个数等于server块的个数。 
     */  
    ngx_array_t                servers;         /* ngx_http_core_srv_conf_t */

	/** 
	  * 包含所有phase,以及注册的phase handler,这些handler在处理http请求时, 
	  * 会被依次调用,通过ngx_http_phase_handler_t的next字段串联起来组成一个 
	  * 链表。 
	  */  
    ngx_http_phase_engine_t    phase_engine;

    /** 
     * 以hash存储的所有request header 
     */  
    ngx_hash_t                 headers_in_hash;

    /** 
     * 被索引的nginx变量 ,比如通过rewrite模块的set指令设置的变量,会在这个hash 
     * 中分配空间,而诸如$http_XXX和$cookie_XXX等内建变量不会在此分配空间。 
     */  
    ngx_hash_t                 variables_hash;

    /** 
     * ngx_http_variable_t类型的数组,所有被索引的nginx变量被存储在这个数组中。 
     * ngx_http_variable_t结构中有属性index,是该变量在这个数组的下标。 
     */  
    ngx_array_t                variables;       /* ngx_http_variable_t */
    ngx_uint_t                 ncaptures;

    /** 
     * server names的hash表的允许的最大bucket数量,默认值是512。 
     */  
    ngx_uint_t                 server_names_hash_max_size;
    ngx_uint_t                 server_names_hash_bucket_size;

    ngx_uint_t                 variables_hash_max_size;
    ngx_uint_t                 variables_hash_bucket_size;

    ngx_hash_keys_arrays_t    *variables_keys;

	/** 
	   * 监听的所有端口,ngx_http_port_t类型,其中包含socket地址信息。 
	   */  
    ngx_array_t               *ports;

    ngx_uint_t                 try_files;       /* unsigned  try_files:1 */
	
    /** 
     * 所有的phase的数组,其中每个元素是该phase上注册的handler的数组。 
     */  
    ngx_http_phase_t           phases[NGX_HTTP_LOG_PHASE + 1];
} ngx_http_core_main_conf_t;
这个配置结构一看就知道很重要了,首先来看servers域,它是一个 ngx_http_core_module模块的srv_conf结构的数组,听起来很奇葩,不过就是这样的,因为在http命令里面可能会包含几个server命令,知道这个也就不会觉得奇怪了,另外还有一个比较重要的域,那就是ports域,它代表所有需要监听的端口。

嗯,接下来看ngx_http_core_module模块的srv_conf类型的配置:

typedef struct {
    /* array of the ngx_http_server_name_t, "server_name" directive */
    ngx_array_t                 server_names;  //server的名字数组

    /* server ctx */
    ngx_http_conf_ctx_t        *ctx;  // 指向包含它的ngx_http_conf_ctx_t结构

    ngx_str_t                   server_name;  //名字

    size_t                      connection_pool_size;
    size_t                      request_pool_size;
    size_t                      client_header_buffer_size;

    ngx_bufs_t                  large_client_header_buffers;

    ngx_msec_t                  client_header_timeout;

    ngx_flag_t                  ignore_invalid_headers;
    ngx_flag_t                  merge_slashes;
    ngx_flag_t                  underscores_in_headers;

    unsigned                    listen:1;  //区别当前server是否监听
#if (NGX_PCRE)
    unsigned                    captures:1;
#endif

    ngx_http_core_loc_conf_t  **named_locations;  //该srv配置的location配置数组
} ngx_http_core_srv_conf_t;
其实这个配置没什么好讲的,许多一看名字就能看的差不多知道什么意思了。接下就是 ngx_http_core_module模块的loc_conf了,嗯,这个结构是ngx_http_core_loc_conf_s,嗯,它的定义太长了,以后用到的时候再讲吧。

接下来我们来看一下http命令的一个例子吧,也就不难明白未什么要这么安排了:

http {    
    include       mime.types;    
    default_type  application/octet-stream;    
    sendfile        on;    
    keepalive_timeout  65;    
    #gzip  on;    
    
    #反向代理配置 ,向内网6台jboss转发    
    upstream jboss {    
        server 192.168.162.35:8080 weight=10;  
        server 192.168.162.11:8080 weight=8;  
        server 192.168.162.61:8080 weight=2;  
    }    
    
    server {    
        listen       2011;    
        server_name  localhost;    
    
        location ~ ^/nginx_status/ {    
            stub_status on;    
            access_log off;    
        }    
    
        location / {    
            proxy_pass http://jboss;    
        }    
    
        error_page   500 502 503 504  /50x.html;    
        location = /50x.html {    
            root   html;    
        }    
    
    }    
    
}   
一个http命令里面可能对应几个server命令,一个server命令又可能会对应好几个location命令。好吧,所以我们就知道一个http模块的配置信息可能存在三个地方,第一个就是http内,server外,这个用main_conf保存,还有一个是server内,location外,这个用srv_conf结构保存,还有的就是在location里面了,因而就用loc_conf配置结构来保存)

好了,已经写了这么多,居然还只是讲完了配置,嗯,那就下一篇在写真正的初始化过程吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值