nginx源码初读(11)--让烦恼从数据结构开始(ngx_command/ngx_module/ngx_conf)
2016-03-10 15:24
846 查看
第一点:ngx_command_t
ngx_core_commands是nginx中的核心模块指令, 它的类型就是ngx_command_t。在每一个module的结构体中,也都有一个ngx_command_t。
第二点:ngx_module_t
对于开发一个模块来说,我们都需要定义一个ngx_module_t类型的变量来说明这个模块本身的信息,从某种意义上来说,这是这个模块最重要的一个信息。它告诉了nginx这个模块的一些信息,上面定义的配置信息,还有模块上下文信息,都是通过这个结构来告诉nginx系统的,也就是加载模块的上层代码,都需要通过定义的这个结构,来获取这些信息。
第三点:ngx_conf_t
该结构体用于Nginx在解析配置文件时描述每个指令的属性,是Nginx程序中非常重要的一个数据结构。
至此,基本的数据结构都看完了,开始学流程和机制吧!
ngx_core_commands是nginx中的核心模块指令, 它的类型就是ngx_command_t。在每一个module的结构体中,也都有一个ngx_command_t。
typedef struct ngx_command_s 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); /* 当nginx在解析配置的时候,如果遇到这个配置指令,将会把读取到的值传递给这个函数进行解析保存。 因为具体每个配置指令的值如何处理,只有定义这个配置指令的人是最清楚的,set可能复杂也可能很简单。 比如errlog模块的“error_log”指令就是调用ngx_error_log写一条日志,并不需要存储什么配置数据。 * cf: 保存从配置文件读取到的原始字符串以及相关信息。这个参数的args字段是一个ngx_str_t类型的数组, 该数组首元素是这个配置指令本身,第二个元素开始才是参数。 cmd: 这个配置指令对应的ngx_command_t结构。 conf: 就是定义的存储这个配置值的结构体 */ ngx_uint_t conf; /* 该字段被NGX_HTTP_MODULE类型模块所用,指定当前配置项存储的内存位置。实际上是使用哪个内存池的问题。 因为http模块对所有http模块所要保存的配置信息,划分了main, server和location三个地方进行存储, 每个地方都有一个内存池用来分配存储这些信息的内存。 这里可能的值为NGX_HTTP_MAIN_CONF_OFFSET、NGX_HTTP_SRV_CONF_OFFSET或NGX_HTTP_LOC_CONF_OFFSET。 当然也可以直接置为0,就是NGX_HTTP_MAIN_CONF_OFFSET。 */ ngx_uint_t offset; /* 指定该配置项值的精确存放位置,一般指定为某一个结构体变量的字段偏移。 比如我们定义了一个结构体A,该项配置的值需要存储到该结构体的b字段。那么在这里就可以填写offsetof(A, b)。 对于有些配置项,它的值不需要保存或者是需要保存到更为复杂的结构中时,这里可以设置为0。 */ void *post; /* 可指向任何一个在读取配置过程中需要的数据,以便于进行配置读取的处理。大多时候不需要,设为0即可。*/ }; static ngx_command_t ngx_core_commands[]; // 保存了核心指令
第二点:ngx_module_t
对于开发一个模块来说,我们都需要定义一个ngx_module_t类型的变量来说明这个模块本身的信息,从某种意义上来说,这是这个模块最重要的一个信息。它告诉了nginx这个模块的一些信息,上面定义的配置信息,还有模块上下文信息,都是通过这个结构来告诉nginx系统的,也就是加载模块的上层代码,都需要通过定义的这个结构,来获取这些信息。
typedef struct ngx_module_s ngx_module_t; struct ngx_module_s { ngx_uint_t ctx_index; /* 在相应模块类的计数,nginx模块分为四种:core、event、http和mail * ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf; */ ngx_uint_t index; /* 模块计数器,按照每个模块在ngx_modules[]数组中的声明顺序,从0开始依次给每个模块赋值 */ ngx_uint_t spare0; ngx_uint_t spare1; ngx_uint_t spare2; ngx_uint_t spare3; ngx_uint_t version; /* 模块当前版本 */ void *ctx; /* 模块上下文,不同类别模块有不同上下文,ngx_http_conf_ctx_t/ngx_mail_conf_ctx_t/... */ ngx_command_t *commands; /* 该模块的命令集,是ngx_command_t数组 */ ngx_uint_t type; /* 模块种类:core、event、http和mail */ ngx_int_t (*init_master)(ngx_log_t *log); // master进程初始化调用 ngx_int_t (*init_module)(ngx_cycle_t *cycle); // 模块初始化调用 ngx_int_t (*init_process)(ngx_cycle_t *cycle); // worker进程初始化调用 ngx_int_t (*init_thread)(ngx_cycle_t *cycle); // 线程初始化调用 void (*exit_thread)(ngx_cycle_t *cycle); // 线程退出调用 void (*exit_process)(ngx_cycle_t *cycle); // worker进程结束调用 void (*exit_master)(ngx_cycle_t *cycle); // master进程结束调用 /* callback:如果该模块需要发生这些行为执行特定的功能,可以通过这些回调函数指针注册一个回调函数接口来实现 */ 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; }; #define NGX_NUMBER_MAJOR 3 #define NGX_NUMBER_MINOR 1 #define NGX_MODULE_V1 0, 0, 0, 0, \ NGX_DSO_ABI_COMPATIBILITY, NGX_NUMBER_MAJOR, NGX_NUMBER_MINOR /* 前7个成员初始化 */ #define NGX_MODULE_V1_PADDING 0, 0, 0, 0, 0, 0, 0, 0 /* 后8个成员初始化 */
第三点:ngx_conf_t
该结构体用于Nginx在解析配置文件时描述每个指令的属性,是Nginx程序中非常重要的一个数据结构。
typedef struct { ngx_file_t file; // 文件 ngx_buf_t *buffer; // 文件内容 ngx_uint_t line; // 文件行数 } ngx_conf_file_t; typedef char a8e0 *(*ngx_conf_handler_pt)(ngx_conf_t *cf, ngx_command_t *dummy, void *conf); typedef struct ngx_conf_s ngx_conf_t struct ngx_conf_s { char *name; // 存放当前解析到的指令 ngx_array_t *args; // 从配置中读取指令的名称和相对应的参数 ngx_cycle_t *cycle; // 对应的cycle(一个进程有一个cycle) ngx_pool_t *pool; // 对应的内存池 ngx_pool_t *temp_pool; // 临时内存池,在解析配置文件的时候使用,之后释放了 ngx_conf_file_t *conf_file; // 配置文件的信息 ngx_log_t *log; // 对应的log void *ctx; // 上下文(指向模块配置信息) ngx_uint_t module_type; // 处理当前指令的模块类型:core、event、mail和http ngx_uint_t cmd_type; // 当前指令的类型 ngx_conf_handler_pt handler; // 自定义的指令处理函数 char *handler_conf; // 作为handler的参数,提供一些handler需要的配置信息 };
至此,基本的数据结构都看完了,开始学流程和机制吧!
相关文章推荐
- Zookeeper - 介绍篇(2)
- 单链表排序之选择排序
- 数据结构——队列
- 【数据结构课程大作业】通信录管理系统
- 【数据结构课程大作业】通信录管理系统
- Tair缓存系统学习 (数据结构存储系统)
- 数据结构 第二章 线性表(3)顺序线性表合并
- 数据结构和算法 (二)数据结构基础之树、二叉树
- 数据结构和算法 (二)数据结构基础、线性表、栈和队列、数组和字符串
- [数据结构和算法]状态树的问题
- bzoj2049[洞穴勘测]纯粹的LCT
- LeetCode 83. Remove Duplicates from Sorted List
- 数据结构——堆栈
- [补充]LCT有关细节的处理及理解
- 【数据结构二叉树复习】
- [数据结构和算法]九宫格算法
- Poj2831 树链剖分||次小生成树
- 个人对数据结构与算法的总结归类
- 数据结构学习->经验总结1
- 【数据结构与算法】(二) c 语言链表的简单操作