概述
总述:
nginx自身是高度模块化设计的,我们可以方便的开发任何基于tcp的模块(比如http模块,mail模块)。
注: 一、开发一个nginx模块,必须遵守的原则有:1、实现模块开发的接口 2、不能有阻塞的系统调用
二、web服务器提高网络效率的方法有:1、使用长连接(keepalive)代替短连接,减少建立、关闭连接带来的开销
2、使用压缩算法来增加相同吞吐量下的信息携带量;3、使用缓存来减少网络交互次数
nginx总结起来就是一个框架和五类模块
一、nginx的模块化设计
nginx的框架代码只占少部分,主要负责建立进程模型并使各个模块有序的执行,当然还包括一系列资源初始化和回收(从某种意义上来说,nginx自定义的数据结构和对系统调用的封装也可以视为框架代码)。
所有的模块都遵循着同样的ngx_module_t接口设计规范
//ngx_module_s是模块的定义
struct ngx_module_s {
//对于一类模块(由下面的type成员决定类别)而言,ctx_index标示当前模块在这类模块中的序号。
//这个成员常常是由管理这类模块的一个nginx核心模块设置的,对于所有的HTTP模块而言,ctx_index
//是由核心模块ngx_http_module设置的。
ngx_uint_t ctx_index;
//index表示当前模块在ngx_modules数组中的序号。Nginx启动的时候会根据ngx_modules数组设置各个模块的index值
ngx_uint_t index;
//spare系列的保留变量,暂未使用
ngx_uint_t spare0;
ngx_uint_t spare1;
ngx_uint_t spare2;
ngx_uint_t spare3;
//nginx模块版本,目前只有一种,暂定为1
ngx_uint_t version;
//模块上下文,每个模块有不同模块上下文,每个模块都有自己的特性,而ctx会指向特定类型模块的公共接口。
//比如,在HTTP模块中,ctx需要指向ngx_http_module_t结构体。
void *ctx;
//模块命令集,将处理nginx.conf中的配置项
ngx_command_t *commands;
//标示该模块的类型,和ctx是紧密相关的。它的取值范围是以下几种:
//NGX_HTTP_MODULE,NGX_CORE_MODULE,NGX_CONF_MODULE,
//NGX_EVENT_MODULE,NGX_MAIL_MODULE
ngx_uint_t type;
//下面7个函数是nginx在启动,停止过程中的7个执行点
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); //初始化进程
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); //退出master
//保留字段,无用,可以使用NGX_MODULE_V1_PADDING来替换
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_t只涉及模块的初始化、退出以及对配置项的处理。如上代码所示,ngx_module_t结构体作为所有模块的通用接口,只定义了init_master 、init_module、init_process、init_thread、exit_thread、exit_process、exit_master这七个回调方法,而init_master 、init_thread、exit_thread这三个方法目前没有使用,后两个是因为nginx目前没有使用线程(因为多线程代码实现更难控制)。他们负责模块的初始化和退出,同时他们可以处理核心结构体ngx_cycle_t(每个进程都有一个该结构体变量)。而ngx_command_t类型的commands数组指定了模块中的配置名和模块处理配置变量的方法,ctx是一个void*指针,他表示一类模块所特有的通用函数接口。
上图包括核心、事件、http、mail四类模块的ctx上下文(配置模块的ctx上下文为空),和ngx_command_t结构。
配置模块是唯一一种只有一个模块的模块类型,这是nginx最底层的模块,他指导着所有模块以配置项为核心来提供功能。因此,他是所有其他模块的基础(但是,单就conf模块对ngx_module_t接口的实现情况来说,他只是实现了include命令,以及进程退出时执行的一个回调方法)。
核心类型的模块一共只有六个:ngx_core_module、ngx_errlog、ngx_events_module、ngx_openssl_module、ngx_http_module、ngx_mail_module。非模块的框架代码只关注于如何调用六个核心模块(大部分nginx模块都是非核心模块)。
typedef struct {
ngx_str_t name; //模块名,即ngx_core_module_ctx结构体对象的
void *(*create_conf)(ngx_cycle_t *cycle); //解析配置项前,nginx框架会调用create_conf方法
char *(*init_conf)(ngx_cycle_t *cycle, void *conf); //解析配置项完成后,nginx框架会调用init_conf方法
} ngx_core_module_t;
ngx_core_module_t上下文是以配置项的解析作为基础的,它提供了create_conf回调方法来创建存储配置项的数据结构,在读取nginx.conf配置文件时,会根据模块中的ngx_command_t把解析出的配置项存放在这个数据结构中;他还提供了init_conf回调方法,用于在解析完配置文件后,使用解析出的配置项初始化模块功能。(但是,很多核心模块,比如http,event,mail并没有实现这个接口,而是在解析配置的时候,比如解析http命令时,调用命令处理函数来创建数据结构和初始化模块功能,http还会在回调函数里创建http模块类型的上下文以及初始化http类的那些模块中的一些属性)。
配置模块和核心模块这两类模块是由nginx的框架代码所定义的,这里的配置模块是所有模块的基础,他实现了最基本的配置项解析功能(就是解析nginx.conf文件)。其他三类模块都不会与框架产生直接关系。事件,http,mail这三类模块,都在核心模块中各有一个模块作为自己的”代言人“,并在同类模块中还有一个作为核心业务与管理功能的模块。
注:每个ngx_listening_t都有一个ngx_connection_t与之对应,反过来则不然。这样是为了使监听套接字操作起来和 连接套接字一样。完全是为了使监听套接字上的事件(只有可读事件)处理和连接套接字统一。
最后
以上就是无奈秀发为你收集整理的nginx架构总结--nginx源码系列(一)的全部内容,希望文章能够帮你解决nginx架构总结--nginx源码系列(一)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复