【Nginx】Nginx的模块与源码结构分析

目录

 

1.Nginx的模块

2.以GZIP模块为例说明学习方法

 3.Nginx模块的定义

4.Nginx的模块划分

5.从源码看目录与子类型模块的对应关系


1.Nginx的模块

设计优良,从2004年发布到现在,没有发生大的变化.
学习Nginx的模块的高明之处,我们在学习一个模块的时候要从以下方面来进行学习:
1.这个模块要被编进Nginx中,这个是前提;
2.这个模块提供了哪些配置项;
3.这个模块什么时候被使用(有些模块只要编进Nginx默认会被使用,有些模块必须使用配置项并正确配置时才会被使用);
4.这个模块提供了哪些变量.


模块说明的官方链接:
http://nginx.org/en/docs/
这里面Modules reference部分给出了每个模块的详细说明.

2.以GZIP模块为例说明学习方法

1.打开官方文档
http://nginx.org/en/docs/http/ngx_http_gzip_module.html
可以看到这个模块的:
(1)Example Configuration(配置示例);
(2)Directives(指令集合);
(3)Embedded Variables(内嵌变量).

2.可以通过编译和看源码的方式来进行进一步学习
在编译好之后:
/home/muten/module/nginx-1.13.7/objs目录下生成ngx_modules.c这个文件,
这个文件里面可以看到哪些模块被编译进Nginx.

Nginx的源码放在/home/muten/module/nginx-1.13.7/src/下.

查看gzip的代码中的指令:
/home/muten/module/nginx-1.13.7/src/http/modules/ngx_http_gzip_filter_module.c
搜索ngx_command_t可以看到一些指令集的说明,如果官网中有些指令或者其他项没有说明,我们
也可以通过查看源码的方式去进行一些探索.


NGX_CONF_FLAG  --配置项的标志
NGX_CONF_TAKE1 --一个参数
NGX_CONF_TAKE2 --两个参数
NGX_CONF_1MORE --一个参数或多个参数

NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF --说明可用在这些模块下


 

 3.Nginx模块的定义

 

 

Nginx的模块是如何划分成不同的子模块的?

源码路径下搜索:
find . -name "*h" | xargs grep "ngx_module_s"可以找到ngx_module_t的定义.

ngx_module_t是每个模块必须具备的数据结构,其中type定义了这个模块属于哪个类型的模块(仅列举出部分),
一共有的模块:
(1)core_module
(2)http_module
(3)event_module
(4)mail_conf_ctx
...



给出上面提到的几个模块的数据结构定义:


(1)typedef struct ngx_module_s 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;//抽象方法
};



(2)ngx_core_module_t
typedef struct {
    ngx_str_t             name;
    void               *(*create_conf)(ngx_cycle_t *cycle);
    char               *(*init_conf)(ngx_cycle_t *cycle, void *conf);
} ngx_core_module_t;



(3)ngx_http_module_t
typedef struct {
    ngx_int_t   (*preconfiguration)(ngx_conf_t *cf);
    ngx_int_t   (*postconfiguration)(ngx_conf_t *cf);

    void       *(*create_main_conf)(ngx_conf_t *cf);
    char       *(*init_main_conf)(ngx_conf_t *cf, void *conf);

    void       *(*create_srv_conf)(ngx_conf_t *cf);
    char       *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf);

    void       *(*create_loc_conf)(ngx_conf_t *cf);
    char       *(*merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf);
} ngx_http_module_t;

(4)ngx_event_module_t

typedef struct {
    ngx_str_t              *name;
    void                 *(*create_conf)(ngx_cycle_t *cycle);
    char                 *(*init_conf)(ngx_cycle_t *cycle, void *conf);
    ngx_event_actions_t     actions;
} ngx_event_module_t;


(5)ngx_mail_conf_ctx_t
typedef struct {
    void                  **main_conf;
    void                  **srv_conf;
} ngx_mail_conf_ctx_t;




4.Nginx的模块划分

 

http_core_module --核心模块
http_conf_module --独立的,解析配置文件

核心模块中会有一类核心模块,比如events,http,mail,stream,它们本身也可以定义
出新的子类型模块,可以看出Nginx框架代码并没有定义http或者core业务,而是通过某些
core_module去定义出新的子类型模块.

Nginx的灵活性是非常强的,如果新出了一类应用,可以通过新增core_module来定义一个新
的模块.

所有事件处理的通用方法我们将它内聚为事件模块(NGINX_EVENT_MODULE),每一类模块中会有一些
通用的共性的部分,对通用的共性的部分,我们会加上core关键字,会把通用部分的功能写在里面,
比如说even_core,ngx_http_core_module,ngx_stream_core_module,我们基础数据结构中的
ngx_module_t的index成员变量会给这些module一个index,表示它的顺序,每个子类型中的所有的
event模块,http模块同样也是有顺序的.每一个core_module一定是排序第一的,因为它定义了
所有子类型模块共同具有的特性.


NGINX_HTTP_MODULE是最复杂的,ngx_http_core_module定义了许多特殊的规则,比如说当一个
http请求进入nginx模块的时候,我们就要为它生成相应,这个生成响应的模块就是请求处理模块,
当把响应发送给浏览器的时候,我们可能要对发送的内容做一些特定的处理(如发送css时可以做压
缩处理,由于信息熵变大,效率会有大幅提升;如发送图片,我们可以用image_filter模块做一些
图片的缩放和裁剪;响应过滤模块专注于把响应做二次处理),还有一个upstream模块,upstream模块是
上游模块,Nginx做正向或者反向代理的时候使用到此模块,专注于在一个请求的内部访问上游服务.

mail和upstream暂时不细说.

5.从源码看目录与子类型模块的对应关系

下面以http子模块作为例子来做出说明:
(一)
所有的框架代码及http_core_module都是放在/home/muten/module/nginx-1.13.7/src/http
这个目录下的;
(二)
官方提供的非框架的(可有可无的模块)放在/home/muten/module/nginx-1.13.7/src/http/modules
目录下,对于http的这些可用可无的模块,分成三类:
(1)处理请求模块(除了响filter模块和upstream模块以外的其他模块都是生成响应或为生成响应而工作的模块);
(2)响应过滤模块(有关键字filter);
(3)与上游服务器发生交互的模块(带有upstream关键字的),这些是在负载均衡或相关工作的.


其他如http,event,mail等子模块也是一样的道理.


当我们拿到一个第三方的新的模块的时候,我们可以首先看它属于哪一类模块,这一类模块会有一些共同
的特性,可以帮助我们理解新模块的作用.

 

 

 

 

 

 

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值