nginx之handler模块笔记
nginx模块 handler模块,filter过滤器模块,upstream模块;
handler模块是客户端访问nginx,nginx接收到请求时就开始处理,接着返回
filter过滤器模块是后端发给nginx,nginx发送给前端的,后端数据到达nginx这,filter可以对响应头和响应体进行修改,在response基础上加入一些东西
upstream模式是nginx转发给后端的模块,比如fastcgi模块。
nginx由许多模块组成,每一个模块要都有自己的运行场景,在conf中配置相应的命令才能运行相应的模块
可以跟着nginx编写一个自己的handle模块,
查看src/http/modules下每个module文件会发现,含有固定的框架,参考Nginx_http_fastcgi_module.c
首先是module模块,
fastcgi module函数原型是
module原型可以看出
宏定义如果写module,要对ngx_module_s 进行初始化,NGX_MODULE_V1就是对一些系统配置信息进行的初始化,紧接着需要自己实现的两个回调函数 ctx 上下文和 commands操作命令,对应fastcgi 模块中的ngx_http_fastcgi_module_ctx和ngx_http_fastcgi_commands,稍后详细解析两个函数,type指定此模块所属的类型,这里使用的是NGX_HTTP_MODULE,其他还有
NGX_STREAM_MODULE,NGX_MAIL_MODULE,NGX_CORE_MODULE,NGX_EVENT_MODULE等。
最后的也是宏定义 #define NGX_MODULE_V1_PADDING 0, 0, 0, 0, 0, 0, 0, 0
完成初始化工作。
================================================================================================
上下文:ngx_http_fastcgi_module_ctx ;
ngx_http_fastcgi_module_ctx这个属于http模块,返回值是ngx_http_module_t模块,原型是
ngx_http_module_t这个变量提供8个回调函数指针,这个模块真实作用是处理配置文件nginx.conf.:
1 preconfiguration:2 postconfiguration:3 create_main_conf:4 init_main_conf:
5 create_srv_conf:6 merge_srv_conf:7 create_loc_conf:8 merge_loc_conf:
执行顺序是3 5 7 1 4 6 8 2;在读取配置的不同阶段中如果对指令有要做相应的操作 实现相应的回调函数添加逻辑即可。
在进程启动解析nginx.conf中的命令时候,遇到http 会进入到 3 5 7 1,遇到 server 时会进入到 5 7,遇到location 会进入到7,最后结尾大括号时会进行 4 6 8 2操作,前面执行了几次5 后面就会执行几次6, 7 和8 也是这种情况。
=========================================================================================================
指令:只有在nginx.conf配置相应的指令,nginx模块才会工作,这里所要做的就是处理配置的相关额度指令操作。指令可以包括多个,这里可以指令使用的是数组形式。如下图
fastcgi部分指令比如 :nginx.conf配置了fastcgi_pass指令,并且客户端请求走到了该loc配置的地方,下图
配置fastcgi地方就会调用ngx_http_fastcgi_pass函数 并且包含一个参数 http://test 传递给函数。函数中所处理的就是业务逻辑。
ngx_command_t 原型是
command原型第一次配置指令名字,第二是配置类型,准确说是指令属性的集合。
NGX_CONF_NOARGS:配置指令不接受任何参数。 NGX_CONF_TAKE1:配置指令接受 1 个参数。
NGX_CONF_TAKE2:配置指令接受 2 个参数。 NGX_CONF_TAKE3:配置指令接受 3 个参数。
NGX_CONF_TAKE4:配置指令接受 4 个参数。 NGX_CONF_TAKE5:配置指令接受 5 个参数。
NGX_CONF_TAKE6:配置指令接受 6 个参数。 NGX_CONF_TAKE7:配置指令接受 7 个参数
NGX_CONF_TAKE12:配置指令接受 1 个或者 2 个参数。 NGX_CONF_TAKE13:配置指令接受 1 个或者 3 个参数。
NGX_CONF_TAKE23:配置指令接受 2 个或者 3 个参数。 NGX_CONF_TAKE123:配置指令接受 1 个或者 2 个或者 3 参数。
NGX_CONF_TAKE1234:配置指令接受 1 个或者 2 个或者 3 个或者 4 个参数。
NGX_CONF_1MORE:配置指令接受至少一个参数。 NGX_CONF_2MORE:配置指令接受至少两个参数。
NGX_CONF_MULTI: 配置指令可以接受多个参数,即个数不定。
NGX_CONF_BLOCK:配置指令可以接受的值是一个配置信息块。也就是一对大括号括起来的内容。里面可以再包括很多的配置指令。比如常见的 server 指令就是这个属性的。
NGX_CONF_FLAG:配置指令可以接受的值是”on”或者”off”,最终会被转成 bool 值。
NGX_CONF_ANY:配置指令可以接受的任意的参数值。一个或者多个,或者”on”或者”off”,或者是配置块。
最后要说明的是,无论如何, nginx 的 配 置 指 令 的 参 数 个 数 不 可 以 超 过NGX_CONF_MAX_ARGS 个。目前这个值被定义为 8,也就是不能超过 8 个参数值。
下面介绍一组说明配置指令可以出现的位置的属性。
NGX_DIRECT_CONF:可以出现在配置文件中最外层。例如已经提供的配置指令 daemon,master_process 等。
NGX_MAIN_CONF: http、mail、events、error_log 等。 NGX_ANY_CONF: 该配置指令可以出现在任意配置级别上。
对于我们编写的大多数模块而言,都是在处理 http 相关的事情,也就是所谓的都是NGX_HTTP_MODULE,对于这样类型的模块,其配置可能出现的位置也是分为直接出现在 http 里面,以及其他位置。
NGX_HTTP_MAIN_CONF: 可以直接出现在 http 配置指令里。 NGX_HTTP_SRV_CONF: 可以出现在 http 里面的 server 配置指令里。
NGX_HTTP_LOC_CONF: 可以出现在 http server 块里面的 location 配置指令里。 NGX_HTTP_UPS_CONF: 可以出现在 http 里面的 upstream 配置指令里。
NGX_HTTP_SIF_CONF: 可以出现在 http 里面的 server 配置指令里的 if 语句所在的 block中。
NGX_HTTP_LMT_CONF: 可以出现在 http 里面的 limit_except 指令的 block 中。
NGX_HTTP_LIF_CONF: 可以出现在 http server 块里面的 location 配置指令里的 if 语句所在在的 block 中。
第三次参数 set 是一个函数指针,nginx在解析配置的时候,如果遇到这个牌配置指令,则会把读取到的值传递给这个函数处理,即实现业务逻辑的函数。
char *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); 参数 cf保存从配置文件读取到的原始字符串以及相关的一些信息;cmd是配置指令对应的ngx_command_t结构;conf就是定义的存储这个配置值的结构体。
第四个conf:此字段被NGX_HTTP_MODULE所用,指定当前配置项存储的内存位置,实际上使用那个内存池的问题。http模块对所有http模块所要保存的配置划分了main server location三个地方,可能的值是NGX_HTTP_MAIN_CONF_OFFSET,NGX_HTTP_SRV_CONF_OFFSET,NGX_HTTP_LOC_CONF_OFFSET。
第五个offset:指的是配置项值的精确存放位置,一般指某一个结构体变量的字段偏移,一般对于配置信息的存储都是使用结构体。
第6个参数:该字段存储一个指针,可以指向一个在读取配置过程中需要的数据,大多情况下都不需要,简单配置0即可。
================================================================================================
handler模块编译和使用
模块开发完之后,需要把这个模块的c代码组织到一个目录中,同时需要编写一个config文件,config文件左右是告诉nginx的编译脚本,该如何进行编译。config固定模式:
ngx_addon_name 为模块所在目录名称。
HTTP_MODULES 系统所有模块,依次添加就可,空格隔开。
NGX_ADDON_SRCS 模块路径,多个的话依次添加,后面空格隔开。
编译时使用--add-module命令 添加文件所在路径的目录。
直接在nginx配置文件中使用命令即可。