Nginx Http框架的理解
Nginx Http框架的理解
HTTP框架是Nginx基础框架的一部分,Nginx的其它底层框架如master-worker进程模型、event模块、mail 模块等。
HTTP框架代码主要有2个模块组成:ngx_http_module和ngx_http_core_module;
我们编写的HTTP模块需要注册到HTTP框架上,才能融入HTTP请求的处理流程中。
当在nginx.conf中存在一个http{...}的配置时,即启用了HTTP框架代码,在nginx配置解析时,就已经为框架建立好了各种数据结构(尤其是HTTP模块的挂载);
当nginx收到请求时,请求完全按照HTTP框架建立好的这种逻辑进行处理。
一、HTTP模块开发基础
开发一个HTTP模块,需要下面几个数据结构:
用于存储从配置文件读进来的相关指令参数;
ngx_str_t name; // 指令名称
ngx_uint_t type; // 指令所在的context和包含的参数个数
char *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); // 解析配置,并将参数存入模块配置结构体中
ngx_uint_t conf; // 指令参数的存储位置
ngx_uint_t offset; // 指令参数的存储偏移量
void *post;
};
b. 指向结构体 ngx_command_t 的指针
c. 指向模块自定义配置结构体的指针
静态的ngx_http_module_t结构体,用来创建和合并三段context (main,server,location),
ngx_int_t (*preconfiguration)(ngx_conf_t *cf); // 在读入配置前调用
ngx_int_t (*postconfiguration)(ngx_conf_t *cf); // 在读入配置后调用,用于挂载handler
void *(*create_main_conf)(ngx_conf_t *cf); // 在创建main配置时调用(比如,用来分配空间和设置默认值)
char *(*init_main_conf)(ngx_conf_t *cf, void *conf); // 在初始化main配置时调用(比如,把原来的默认值用nginx.conf读到的值来覆盖)
void *(*create_srv_conf)(ngx_conf_t *cf); // 在创建server配置时调用
char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf); // 合并server和main配置时调用
void *(*create_loc_conf)(ngx_conf_t *cf); // 创建location配置时调用,用于为指令参数结构体分配内存和初始化
char *(*merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf); // 合并location和server配置时调用
} ngx_http_module_t;
这些回调是在ngx_http_block()解析http{...}配置时完成的:
当遇到一个 http{...} 时,HTTP框架会调用所有HTTP模块可能实现的create_main_conf、create_srv_conf、create_loc_conf生成存储main级别配置参数结构体;
当遇到一个server{...}时,HTTP框架会调用所有HTTP模块可能实现的create_srv_conf、create_loc_conf生成存储server级别配置参数结构体;
当遇到一个location{...}时,HTTP框架会调用所有HTTP模块可能实现的create_loc_conf生成存储location级别配置参数结构体;
因此,我们开发的HTTP模块中create_loc_conf方法被调用的次数等于http{...}、server{...}、location{...}在nginx.conf出现的次数之和;
create_srv_conf方法被调用的次数等于server{...}、location{...}在nginx.conf出现的次数之和;
由于只有一个http{...},所以create_main_conf方法只会被调用一次;
HTTP创建了如此多的结构体来存放配置项,是为了解决同名配置项的合并问题。
struct ngx_module_s {
ngx_uint_t ctx_index; // 在所有的HTTP模块中的序列号
ngx_uint_t index; // 在所有模块中的序列号
ngx_uint_t spare0;
ngx_uint_t spare1;
ngx_uint_t spare2;
ngx_uint_t spare3;
ngx_uint_t version;
void *ctx; // 模块上下文
ngx_command_t *commands; // 模块配置指令
ngx_uint_t type; // 模块类型,HTTP模块应为NGX_HTTP_MODULE
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;
};
注意:在configure之后生成的文件 objs/ngx_modules.c 中包含了模块的编译顺序。
1、解析HTTP配置的流程
首先要理解 ngx_conf_parse() 的递归解析流程;
nginx在解析nginx.conf的时候,没读取一行配置项,就执行该配置项的解析回调(handler);
Nginx Http框架的理解的更多相关文章
- Nginx:HTTP框架是如何介入请求
参考资料 <深入理解Nginx>(陶辉) Nginx事件模块博客地址:http://www.cnblogs.com/runnyu/p/4914698.html Nginx是一个事件驱动构架 ...
- iOS10通知框架UserNotification理解与应用
iOS10通知框架UserNotification理解与应用 一.引言 关于通知,无论与远程Push还是本地通知,以往的iOS系统暴漏给开发者的接口都是十分有限的,开发者只能对标题和内容进行简单的定义 ...
- Java面试之五大框架的理解
五大框架(springMVC,struts2,spring,mybatis,hibernate) 说说你对springMVC框架的理解? 简要口述(如果感觉说的少可以在完整答案里面挑几条说) Spri ...
- 对SSH三大框架的理解
SSH框架一般指的是Struts.Spring.Hibernate,后来Struts2代替了Struts.最近5年,Struts2已经被Spring MVC代替,而Hibernate基本也被iBati ...
- Nginx学习之十一-Nginx启动框架处理流程
Nginx启动过程流程图 下面首先给出Nginx启动过程的流程图: ngx_cycle_t结构体 Nginx的启动初始化在src/core/nginx.c的main函数中完成,当然main函数是整个N ...
- nginx配置之深入理解
继上一篇<debian+nginx配置初探--php环境.反向代理和负载均衡>成功之后,有点小兴奋,终于不用整lvs那么复杂来搞定负载,但还是有很多概念没弄清楚. 什么是CGI.FastC ...
- Django_web框架的理解
web框架的本质 import socket sk = socket.socket() sk.bind(("127.0.0.1", 80)) sk.listen() while T ...
- 对spring框架的理解
spring框架的两大核心理念就是IOC和AOP,在面试的时候经常会被问到你对spring的理解.下面大致的说一下我对spring的理解. 一.IoC 1.1.什么是IoC 众所周知,IoC就是控制反 ...
- nginx 限速最容易理解的说明
nginx 限速研究汇报 写在前面 这两天服务器带宽爆了,情况如下图: 出于降低带宽峰值的原因,我开始各种疯狂的研究nginx限速.下面是我研究过程中的心得!(花了好几个小时的时间写的人生第一篇技术类 ...
随机推荐
- [转]World Wind Java开发之四——搭建本地WMS服务器
在提供地理信息系统客户端时,NASA还为用户提供了开源的WMS Server 服务器应用:World Wind WMS Server.利用这个应用,我们可以架设自己的WMS服务并使用自己的数据(也支持 ...
- 供应商和管理员查看供应商地址簿信息SQL
--管理员查看地址簿 SELECT hps.party_site_id, hps.party_site_name AS address_name, 'CURRENT' AS status, hzl.a ...
- Java Concurrency in Practice 读书笔记 第十章
粗略看完<Java Concurrency in Practice>这部书,确实是多线程/并发编程的一本好书.里面对各种并发的技术解释得比较透彻,虽然是面向Java的,但很多概念在其他语言 ...
- linux内核分析 第七周
一.课堂相关 (一)预处理.编译.链接和目标文件的格式 1.可执行程序是怎么得来的 C代码--预处理--汇编代码--目标代码--可执行文件 预处理负责把include的文件包含进来及宏替换工作. he ...
- 20145208 《Java程序设计》第8周学习总结
20145208 <Java程序设计>第8周学习总结 教材学习内容总结 NIO与NIO2 NIO与IO的区别 IO NIO 面向流 面向缓冲 阻 ...
- 玩转数据库之 Group by Grouping
有的时候我们要从数据库里把数据组织成树结构再展现到页面上 像下面这样 今天我们用Group 和Grouping实现它,并总结一下它俩. 先看一下概念,再用代码一点一点去理解它们,最后我会给出完整的代码 ...
- (原创)JS闭包看代码理解
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="C ...
- 你会swap吗,按值传递还是按引用?
问题 1.Java到底是按值传递(Call by Value),还是按引用传递(Call by Reference)? 2.如下面的代码,为什么不能进行交换? public CallBy swap2( ...
- 第二章:Javascript词法结构
编程语言的词法结构是一套基础性的规则,用来描述你如何编写这门语言.作为语法的基础,它规定了变量名是怎么样的,如何写注释,以及语句之间是如何区分的.本节用很短的篇幅来介绍javascript的词法结构. ...
- 第三章:Javascript类型、值和变量。
计算机程序的运行需要对值(value)比如数字3.14或者文本"hello world"进行操作,在编程语言中,能够表示并操作的值的类型叫做数据类型(type),编程语言最基本的特 ...