ngx_core_module模块的初始化

ngx_core_module的初始化在ngx_init_cycle函数中进行,包括create_conf和init_conf两个阶段。在init_conf阶段, ngx_core_module_init_conf函数负责设置如daemon、master、user、username、usergroup和lock_file等配置信息。
这个应该是要分析的第一个模块吧,首先看该模块的定义(src/core/nginx.c):
static ngx_core_module_t  ngx_core_module_ctx = {
    ngx_string("core"),
    ngx_core_module_create_conf,   //创建配置的函数
    ngx_core_module_init_conf     //初始化配置的函数
};


ngx_module_t  ngx_core_module = {
    NGX_MODULE_V1,
    &ngx_core_module_ctx,                  /* module context */   //模块的上下文
    ngx_core_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
};
嗯,一看就知道该模块是属于core模块类型,前一篇文章已经知道,每一个一个core模块在ngx_init_cycle当中都会首先调用create_conf函数创建该模块的配置,然后调用init_conf函数初始化配置,这里我们首先看core模块的配置结构的定义(src/core/ngx_cycle.h):

  //core类型的模块的配置结构的定义
typedef struct {
     ngx_flag_t               daemon;
     ngx_flag_t               master;

     ngx_msec_t               timer_resolution;

     ngx_int_t                worker_processes;
     ngx_int_t                debug_points;

     ngx_int_t                rlimit_nofile;
     ngx_int_t                rlimit_sigpending;
     off_t                    rlimit_core;

     int                      priority;

     ngx_uint_t               cpu_affinity_n;
     uint64_t                *cpu_affinity;

     char                    *username;  //用户名
     ngx_uid_t                user;   //用户id
     ngx_gid_t                group;   //组id

     ngx_str_t                working_directory;
     ngx_str_t                lock_file;

     ngx_str_t                pid;
     ngx_str_t                oldpid;

     ngx_array_t              env;
     char                   **environment;

#if (NGX_THREADS)
     ngx_int_t                worker_threads;
     size_t                   thread_stack_size;
#endif

} ngx_core_conf_t;
首先ngx_core_module模块会调用create_conf函数来创建该配置结构,并会将其保存到ngx_cycle的conf_ctx相应的区域中,该函数对应的是ngx_core_module_create_conf函数(src/core/nginx.c):
static void *
ngx_core_module_create_conf(ngx_cycle_t *cycle)
{
    ngx_core_conf_t  *ccf;  //申明配置结构的指针

    ccf = ngx_pcalloc(cycle->pool, sizeof(ngx_core_conf_t));  //在全局变量ngx_cycle的内存池中分配配置结构的内存
    if (ccf == NULL) {
        return NULL;
    }

    /*
     * set by ngx_pcalloc()
     *
     *     ccf->pid = NULL;
     *     ccf->oldpid = NULL;
     *     ccf->priority = 0;
     *     ccf->cpu_affinity_n = 0;
     *     ccf->cpu_affinity = NULL;
     */

    ccf->daemon = NGX_CONF_UNSET;
    ccf->master = NGX_CONF_UNSET;
    ccf->timer_resolution = NGX_CONF_UNSET_MSEC;

    ccf->worker_processes = NGX_CONF_UNSET;
    ccf->debug_points = NGX_CONF_UNSET;

    ccf->rlimit_nofile = NGX_CONF_UNSET;
    ccf->rlimit_core = NGX_CONF_UNSET;
    ccf->rlimit_sigpending = NGX_CONF_UNSET;

    ccf->user = (ngx_uid_t) NGX_CONF_UNSET_UINT;
    ccf->group = (ngx_gid_t) NGX_CONF_UNSET_UINT;

#if (NGX_THREADS)
    ccf->worker_threads = NGX_CONF_UNSET;
    ccf->thread_stack_size = NGX_CONF_UNSET_SIZE;
#endif

    if (ngx_array_init(&ccf->env, cycle->pool, 1, sizeof(ngx_str_t))
        != NGX_OK)
    {
        return NULL;
    }

    return ccf;
}

在ngx_init_cycle函数中,我们可以知道core类型在调用create_conf之后,会接着调用init_conf函数来具体初始化具体的配置结构的一些信息。ngx_core_module模块也就会调用相应的ngx_core_module_init_conf函数来初始化其配置结构的相应的信息,函数主要分一些步骤:

(1)初始化daemon,master等,采用的是直接赋值的方式:

ngx_conf_init_value(ccf->daemon, 1);
    ngx_conf_init_value(ccf->master, 1);
    ngx_conf_init_msec_value(ccf->timer_resolution, 0);

    ngx_conf_init_value(ccf->worker_processes, 1);
    ngx_conf_init_value(ccf->debug_points, 0);
(2)初始化pid以及oldpid

(3)初始化user,username,usergroup

(4)初始化lock_file

在 Nginx 模块开发中,模块初始化的核心任务之一是将请求处理函数添加到 HTTP 请求处理的各个阶段。Nginx 采用多阶段处理机制来处理 HTTP 请求,开发者通常将自定义处理逻辑插入到特定阶段,例如 `content` 阶段。 模块初始化通常通过模块的 `ctx` 结构体定义,并在模块初始化函数中注册请求处理函数。以下是一个典型的模块初始化结构: ```c static ngx_http_module_t ngx_http_hello_module_ctx = { NULL, /* preconfiguration */ ngx_http_hello_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ NULL, /* create server configuration */ NULL, /* merge server configuration */ NULL, /* create location configuration */ NULL /* merge location configuration */ }; ``` 其中,`ngx_http_hello_init` 是模块初始化函数,通常用于注册请求处理阶段的回调函数。要将处理函数添加到 `content` 阶段,需要通过模块的命令结构体指定处理函数,或在模块初始化时动态添加。 以下是一个将处理函数添加到 `content` 阶段的示例代码: ```c static ngx_int_t ngx_http_hello_init(ngx_conf_t *cf) { ngx_http_handler_pt *h; ngx_http_core_main_conf_t *cmcf; cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers); if (h == NULL) { return NGX_ERROR; } *h = ngx_http_hello_content_handler; return NGX_OK; } ``` 上述代码中,`ngx_http_hello_content_handler` 是自定义的请求处理函数,其定义如下: ```c static ngx_int_t ngx_http_hello_content_handler(ngx_http_request_t *r) { ngx_int_t rc; ngx_buf_t *b; ngx_chain_t out; if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) { return NGX_HTTP_NOT_ALLOWED; } rc = ngx_http_discard_request_body(r); if (rc != NGX_OK) { return rc; } r->headers_out.content_type.len = sizeof("text/plain") - 1; r->headers_out.content_type.data = (u_char *)"text/plain"; b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); if (b == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } b->pos = (u_char *)"Hello, world!"; b->last = b->pos + sizeof("Hello, world!") - 1; b->memory = 1; b->last_buf = 1; out.buf = b; out.next = NULL; r->headers_out.status = NGX_HTTP_OK; rc = ngx_http_send_header(r); if (rc == NGX_ERROR || rc > NGX_OK) { return rc; } return ngx_http_output_filter(r, &out); } ``` 通过这种方式,开发者可以将自定义的处理函数插入到 Nginx 的请求处理流程中,从而实现特定的业务逻辑[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值