资讯专栏INFORMATION COLUMN

分析Nginx 源码 - ngx_module_t接口总结

sunnyxd / 1985人阅读

摘要:关于有一套设计良好的源码,以供分析,本文从结构体来分析源码结构。总结初次阅读源码,先从结构体开始学习,开篇之作,再接再厉。

关于

nginx有一套设计良好的源码,以供分析,本文从ngx_module_t结构体来分析nginx源码结构。ngx_module_t是整个nginx的关键,它提供了整个nginx的模块化的基础。因此,看懂ngx_module_t结构体才能开始入门nginx源码阅读。

ngx_module_t结构体介绍

该结构体描述了整个模块的所有信息,为核心模块进行初始化和调用提供了接口,整个结构体的初始化源码如下:

struct ngx_module_s {
    ngx_uint_t            ctx_index;
    ngx_uint_t            index;

    char                 *name;

    ngx_uint_t            spare0;
    ngx_uint_t            spare1;

    ngx_uint_t            version;
    const char           *signature;

    void                 *ctx;
    ngx_command_t        *commands;
    ngx_uint_t            type;

    ngx_int_t           (*init_master)(ngx_log_t *log);

    ngx_int_t           (*init_module)(ngx_cycle_t *cycle);

    ngx_int_t           (*init_process)(ngx_cycle_t *cycle);
    ngx_int_t           (*init_thread)(ngx_cycle_t *cycle);
    void                (*exit_thread)(ngx_cycle_t *cycle);
    void                (*exit_process)(ngx_cycle_t *cycle);

    void                (*exit_master)(ngx_cycle_t *cycle);

    uintptr_t             spare_hook0;
    uintptr_t             spare_hook1;
    uintptr_t             spare_hook2;
    uintptr_t             spare_hook3;
    uintptr_t             spare_hook4;
    uintptr_t             spare_hook5;
    uintptr_t             spare_hook6;
    uintptr_t             spare_hook7;
};

ngx_module_s的关键部分在于中间的几个函数指针,以ngx_core_module核心模块为例:

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
};

关于NGX_MODULE_V1NGX_MODULE_V1_PADDING2个关键字是2个宏定义,主要用于快速声明而已,剩下的属性可以分为4类:模块类型、模块命令、模块上下文、预留接口。我们可以先了解模块命令结构体(ngx_command_s)

模块命令结构体(ngx_command_s)

ngx_command_s结构体是用来分析整个配置文件关键字的工具,源码如下:

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;
};
ngx_module_t结构体接口位置 init_master接口

字面意思是初始化master进程时候进行调用,但是暂未找到接口位置。

init_module接口

该接口是在模块初始化的时候调用,调用位置在于ngx_init_cycle>ngx_init_modules的代码中:

ngx_int_t
ngx_init_modules(ngx_cycle_t *cycle)
{
    ngx_uint_t  i;

    for (i = 0; cycle->modules[i]; i++) {
        if (cycle->modules[i]->init_module) {
            if (cycle->modules[i]->init_module(cycle) != NGX_OK) {
                return NGX_ERROR;
            }
        }
    }

    return NGX_OK;
}
init_process接口

该接口分别在ngx_worker_process_initngx_single_process_cycle,2者会在不同的模式下运行,所以只会初始化一次。我们以多进程模式为例,其路径在:ngx_master_process_cycle>ngx_start_worker_processes>ngx_worker_process_cycle,关键代码如下:

static void
ngx_worker_process_init(ngx_cycle_t *cycle, ngx_int_t worker)
{
 ... ...
    for (i = 0; cycle->modules[i]; i++) {
        if (cycle->modules[i]->init_process) {
            if (cycle->modules[i]->init_process(cycle) == NGX_ERROR) {
                /* fatal */
                exit(2);
            }
        }
    }
 ... ...
}
init_thread接口

字面意思是初始化线程进程时候进行调用,但是暂未找到接口位置。

exit_thread接口

字面意思是退出线程进程时候进行调用,但是暂未找到接口位置。

exit_process接口

该接口于init_process接口对应,其路径在:ngx_master_process_cycle>ngx_start_worker_processes>ngx_worker_process_exit,条件是在出现中断,或者没有时间片的时候退出线程并调用。关键代码如下:

static void
ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
{
    ngx_int_t worker = (intptr_t) data;

    ngx_process = NGX_PROCESS_WORKER;
    ngx_worker = worker;

    ngx_worker_process_init(cycle, worker);

    ngx_setproctitle("worker process");

    for ( ;; ) {

        if (ngx_exiting) {
            if (ngx_event_no_timers_left() == NGX_OK) {
                ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
                ngx_worker_process_exit(cycle);
            }
        }

        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle");

        ngx_process_events_and_timers(cycle);

        if (ngx_terminate) {
            ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
            ngx_worker_process_exit(cycle);
        }
    }
    ... ...
}
exit_master接口

该接口是当master进程退出时调用,其路径在:ngx_master_process_cycle>ngx_master_process_exit,关键代码如下:

void
ngx_master_process_cycle(ngx_cycle_t *cycle)
{
    ... ...

    for ( ;; ) {
        ... ...
        
        if (!live && (ngx_terminate || ngx_quit)) {
            ngx_master_process_exit(cycle);
        }

        ... ...
    }
}

等于当出现退出或中断信号,或者进程不再存活的时候,进行退出操作。

总结

初次阅读nginx源码,先从结构体开始学习,开篇之作,再接再厉。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/39652.html

相关文章

  • Nginx 源码分析:从模块到配置(上)

    摘要:结构体数组,用来表示该模块可以在配置文件中配置的项目,及其操作指令。 源文件路径 srccore gx_conf_file.h srccore gx_conf_file.c 主要内容 本篇的主要目的在于分析Nginx的配置功能。由于Nginx的配置基本就是对模块的配置,因此,在讨论配置功能之前,需要先分析Nginx的模块功能。 对于模块功能,这里的重点不在于某个模块的细节,而...

    gotham 评论0 收藏0
  • Nginx源码分析Nginx的编译

    摘要:用来组织编译流程。会构造的编译选项赋值针对版本操作系统等添加参数。向写入通用的头文件检查操作系统特性。以下脚本为核心原文件生成的规则。为不同的系统做了大量的编译优化,充分挖掘性能。代码量大,手动编写枯燥易出错。 周生政 nginx构建 使用shell语言生成makefile,以及ngx_auto_config.h,ngx_auto_headers.h,ngx_modules.c。其中n...

    shery 评论0 收藏0
  • Nginx 源码分析:从模块到配置(下)

    摘要:每个模块由以下几部分构成结构体代表模块本身,其指针被放入数组中。结构体用来表示模块的配置内容,其中部分成员可以通过配置文件进行配置。调用该中的函数,该函数最终初始化模块对应的结构体,完成配置。因此,分析源码中的配置指令,就是分析结构体。 本篇的上篇 Nginx 源码分析:从模块到配置(上),建议阅读本篇前先阅读上篇。 关于模块 Nginx的架构高度模块化。每个模块各司其职,组合在一...

    Chao 评论0 收藏0
  • Nginx源码分析Nginx配置文件解析(一)

    摘要:本文将从源码从此深入分析配置文件的解析,配置存储,与配置查找。在学习配置文件的解析过程之前,需要先了解一下模块与指令的一些基本知识。 运营研发团队 李乐 配置文件是nginx的基础,对于学习nginx源码甚至开发nginx模块的同学来说更是必须深究。本文将从源码从此深入分析nginx配置文件的解析,配置存储,与配置查找。 看本文之前读者可以先思考两个问题: 1.nginx源码中随处可以...

    JasonZhang 评论0 收藏0
  • nginx架构

    摘要:反向代理反向代理反向代理负载均衡鉴权限流等逻辑架构在逻辑上分为入口层,模块化的功能处理层,系统调用层。多个共同监听事件并处理,反向代理会把请求转发给后端服务。 一.概述 本文将深入剖析nginx的架构。 第一部分介绍nginx现有框架,用典型的4+1视图阐述,包括逻辑架构,开发架构,运行架构,物理架构,功能用例,nginx为单机服务,不考虑物理架构。其中功能用例概述nginx功能;逻辑...

    smartlion 评论0 收藏0

发表评论

0条评论

sunnyxd

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<