第三十一讲:nginx的模块究竟是什么?
Nginx之所以能有如此多的特性,是因为有大量的第三方开发者,在为它开发模块,Nginx之所以有这么丰富的生态圈,则是因为它的模块设计非常的优良,就比如TCP协议,它从上个世纪70年代设计至今,没有做过大的变动,接下来我们来看下nginx的模块设计究竟有什么高明之处?
理解Nginx模块,
(1):首先我们要保证它是编译到我们nginx的binary的二进制文件的;
(2):其次我们要了解,这个nginx模块究竟提供了哪些配置项?
(3):还要了解模块何时被使用?因为有的模块只要编译进nginx就会默认被使用,而有的模块必须使用相应的配置项,必须配置正确时,模块才会被使用;
(4):这个模块提供了哪些变量?
接下来,我们以实际的场景来给大家演示如何看这四点
我们在官方文档的documentation中可以看到,所有的官方模块都有完善的说明:
比如,我们在做gzip压缩的时候,我们可以找到一个叫ngx_http_gzip_module;
我们打开这个链接可以看到对这个链接的简要描述,以及它所支持的配置,即指令,
比如指令gzip on |off 以及相关描述.
在最下方 ,放了相关的变量;
那么以上四点怎么看尼?我们可以看编译以及源码的方式去看每一个配置项被提供的;
首先我们开始编译时,我们在它的源代码根目录下,会执行./configure --with --without 甚至用--add-module引入nginx的第三方模块的方式,把我们的nginx编译到nginx中;但我怎么确定它确实编译到我们的nginx中了尼?
我们可以在configure以后,到objs目录下,在此目录下会生成一个文件,叫ngx_modules.c
我们打开这个文件:
我们可以看到一个数组,叫ngx_modules[],这个数组中是包含了所有编译进nginx中中的模块;在这里我们找一找刚才的gzip
输入 /gzip 再按住Enter 可以查询;
(1):我们可以找到这个gzip模块已经被编译到nginx中了;
(2):我们再看这个gzip模块究竟提供了哪些指令了尼?
我们看到它的源代码中,一个叫command的这样的一个数据结构;
src/http/modules 存放模块的源代码
打开以后在这个源文件中我们搜索ngx_command_t这样的一个结构体,它是每个模块里面唯一的;
这个结构体是一个数组;数组中的每一个 成员是它所支持的指令名:
每个指令名后面携带的参数表示他可以跟几个参数,这个参数什么样的类型,是空间类的还是时间类的;
这样我们就确定了它支持哪些指令;
所以即使它没有在官方文档中去说明我们也可以看到;
接下来我们再看下nginx模块是如何被定定义的?
ngx_module_t 用来说明每一个模块的结构体,这个结构体中有一个成员叫commands 也就是ngx_command_t 也就是我们刚刚在源代码中看到的ngx_command_t;而ngx_command_t这个数组中,每一个元素就是一个指令,以及它所处理的方法以及这些指令可以跟些什么样的参数;ngx_module_t是通用的模块;但是我们看到,但是我们实际上有许多不同类型的应用;比如HTTP,比如stream这是完全不同的应用;那么每一类应用都有许多模块组成,所以我们把模块又细分为子模块;ngx_core_module_t 就是核心模块;ngx_http_module_t就是http模块等,都必须遵循同样的规则;每一类子模块它会重新定义一些新的规则;比如ngx_http_module_t 这个http模块定义了八个回调方法;
而ngx_event_module事件模块它又定义了事件操作相关的方法;
再回头看ngx_module_t 它会定义所有模块的一个顺序,因为它里面有个index序号;这个模块的顺序仍然非常重要;它会决定有些模块如果跟其它模块是冲突的话,先生成的模块会阻碍后生成的模块发挥作用,这个我们后面再说,nginx的模块首先要做到高内聚,也就是说相应独立的功能是在同一个模块代码中的;它的抽象尼是做的非常好的;比如说我们刚才所说的ngx_module_t中的command 它就定义了很多配置;它的启停回调方法
有一些定制化的需求,如果希望在集群刚刚启动的时候,做一些什么样的事情,完全可以在这些回调方法中去做,或者说我们找到一些第三方模块;它们就在启停的地方完成了相应的工作;
Nginx模块拥有非常好的设计;nginx模块是我们理解诸多特性的一个基础;
接下来 我们去详细的分析nginx模块中细分了哪些大类的子模块;这些子模块拥有哪些特性;