Nginx:解析HTTP配置的流程

参考资料:深入理解Nginx(陶辉)

书中有详细的讲解,这里只用本人的理解梳理一下该流程。

一点提议:对于像我这样的新手,面对暂时看不懂章节,建议先往下看一下(可能就会有新的理解或灵感),而不要死磕在某一章节。

几个重要的数据结构

定义一个用于测试的结构体

我们的测试模块将使用该结构体来存放配置信息,该结构只存放一个ngx_str_t。

typedef struct {
  ngx_str_t          my_str;
} ngx_http_mytest_conf_t;

先看看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);                       //当需要创建数据结构用户存储main级别的全局配置项时候调用
  char *(*init_main_conf)(ngx_conf_t *cf, void *conf);             //初始化main级别配置项
  void *(*create_srv_conf)(ngx_conf_t *cf);                        //当需要创建数据结构用户存储srv级别的全局配置项时候调用
  char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf); //合并server级别的配置项
  void *(*create_loc_conf)(ngx_conf_t *cf);                        //当需要创建数据结构用户存储loc级别的全局配置项时候调用
  char *(*merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf); //合并location级别的配置项
} ngx_http_module_t;

HTTP框架定义了3个级别的配置main、srv、loc,分别表示直接出现在http{}、server{}、location{}块内的配置项。
例如:当解析遇到http{}配置块时,会调用create_main_conf回调函数来创建并返回每个HTTP模块对应的结构体(对于我们的测试模块是ngx_http_mytest_conf_t)。

我们的mytest模块实现create_loc_conf的是ngx_http_mytest_create_loc_conf方法

static void *ngx_http_mytest_create_loc_conf(ngx_conf_t *cf)
{
  //创建mytest模块对应的结构体ngx_http_mytest_conf;
  ngx_http_mytest_conf_t *mycf;
  mycf=(ngx_http_mytest_conf_t *)ngx_pcalloc(cf->pool,sizeof(ngx_http_mytest_conf_t));
  if(mycf==NULL){
    return NULL;
  }
  return mycf;
}

那么Nginx是怎么保存这些配置信息的呢?

再看看ngx_http_conf_ctx_t结构

typedef struct {
  /* 指针数组,数组中的每个元素指向所有HTTP模块create_main_conf方法产生的结构体*/
  void **main_conf;
  /* 指针数组,数组中的每个元素指向所有HTTP模块create_srv_conf方法产生的结构体*/
  oid **srv_conf;
  /* 指针数组,数组中的每个元素指向所有HTTP模块create_loc_conf方法产生的结构体*/
  void **loc_conf;
} ngx_http_conf_ctx_t;

用于定义模块的配置参数的结构体ngx_command_t

typedef struct ngx_command_s ngx_command_t;
struct ngx_command_s {
  ngx_str_t name;
  ngx_uint_t type;
  char *(*set)(ngx_conf_t *cf,ngx_command_t *cmd,void *conf);
  ngx_uint_t conf;
  ngx_uint_t offset;
  void *post;
}

其中各个成员代表的意义如下:
name:配置项的名称
type:配置项的参数类型、参数个数以及配置项可以在哪些位置出现(http、server、location等)
set:处理配置项的回调方法。Nginx提供了14个预设的解析配置项的方法。
conf:对于HTTP模块,conf是必须设置的,它的取值范围见下表

offset:当前配置项在整个存储配置项的结构体中的偏移位置。对于使用Nginx预设的解析方法:
         Nginx首先通过conf成员找到应该用哪个结构体来存放,然后通过offset成员找到这个结构体中的相应成员,以便存放该配置。

在mytest模块中,我们将这样定义一个ngx_command_t数组

static ngx_command_t ngx_http_mytest_commands[] = {
  {
    ngx_string("test_str"),   //配置项名称
    NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,    //配置项只能出现在location块中并且配置参数数量为1个
    ngx_conf_set_str_slot,  //使用预设的解析方法解析配置参数,表示我们希望用ngx_str_t类型的变量来保存这个配置项的参数
    NGX_HTTP_LOC_CONF_OFFSET,  //使用create_loc_conf方法产生的结构体来存储解析出的配置项参数
    offsetof(ngx_http_mytest_conf_t,my_str); //与上面两个成员一起使用,通过这3个成员来找到该配置参数存放的位置(ngx_http_mytest_conf_t.my_str)。
    NULL
  },
  ngx_null_command
};

HTTP配置的流程

1.主循环调用配置文件解析器解析nginx.conf文件。

2.当发现配置文件中含有http{}关键字时,HTTP框架开始启动。

3.初始化所有HTTP模块的序列号,并创建ngx_http_conf_ctx_t结构。

4.调用每个HTTP模块的create_main_conf、create_srv_conf、create_loc_conf方法。

5.把各HTTP模块上述3个方法返回的地址依次保存到ngx_http_conf_ctx_t结构体的3个数组中(如果某个模块没有定义相应的方法,则为NULL)。

6.调用每个HTTP模块的preconfiguration方法。

7.如果preconfiguration返回失败,那么Nginx进程将会停止。

8.HTTP框架开始循环解析nginx.conf文件中http{...}里面的所有配置项

9.配置文件解析器在检测到一个配置项后,会遍历所有HTTP模块,检查它们的ngx_command_t数组中的name项是否与配置项名相同。

10.如果找到一个HTTP模块对这个配置项感兴趣,就调用ngx_command_t结构中的set方法来处理该配置项。

11.如果set方法返回失败,那么Nginx进程会停止。

12.配置文件解析器继续检查配置项。如果发现server{...}配置项,就会调用ngx_http_core_module模块来处理。

13.ngx_http_core_module模块在解析server{...}之前,也会如第三步一样建立ngx_http_conf_ctx_t结构,并调用每个HTTP模块的create_srv_conf、create_loc_conf回调方法。

14.将上一步各HTTP模块返回的指针地址保存到ngx_http_conf_ctx_t对应的数组中。

15.开始调用配置文件解析器来处理server{...}里面的配置项。

16.继续重复第9步的过程,遍历nginx.conf中当前server{...}内的所有配置项。

17.配置文件解析器继续解析配置项,如果发现当前server块已经遍历到尾部,则返回ngx_http_core_module模块。

18.返回配置文件解析器继续解析后面的配置项。

19.配置文件解析器继续解析配置项,如果发现处理到了http{...}的尾部,返回个HTTP框架继续处理。

20.调用merge_srv_conf、merge_loc_conf等方法合并这些不同块中每个HTTP模块分配的数据结构。

21.HTTP框架处理完毕http配置项,返回给配置文件解析器继续处理其他http{...}外的配置项。

22.配置文件解析器处理完所有配置项后告诉Nginx主循环配置项解析完毕,这是Nginx才会启动Web服务器。

注意:上面还有一些我们没有列出来的步骤(如发现其他server块或者location块)。它们都会创建ngx_http_conf_ctx_t结构。

HTTP配置模型的内存布局

关于mytest模块的完整代码将在下一次更新

时间: 2024-10-25 15:04:48

Nginx:解析HTTP配置的流程的相关文章

Nginx防盗链以及访问控制,Nginx解析php配置和代理

Nginx防盗链 1.编辑配置文件: [[email protected] ~]# vim /usr/local/nginx/conf/vhost/test.com.conf location ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip|doc|pdf|gz|bz2|jpeg|bmp|xls)$ { expires 7d; valid_referers none blocked server_names *.test.com ; if ($invalid_refer

Nginx+Tomcat+SSL配置(包括https跳转及腾讯免费SSL申请流程)

网上有非常多的nginx+ssl相关配置的文档,但大都是很简单的写一下如何改配置文件,并没有完整的配置流程,我自己找了很久才找到免费的ssl证书,然后直到网站可以正常运行经过了很多测试,写这篇的目的也是为了帮助阅读者能少走些弯路,还有就是不得不提醒,免费证书只有一年的使用期,而且安全度肯定不如收费证书,这点上希望大家能有所权衡! 一.免费SSL证书申请 网址:https://console.qcloud.com/ssl/apply 1. 2. 3.在你申请的二级域名上添加CNAME记录,添加完成

Nginx+Tomcat+Memcached负载均衡配置完整流程(多方总结,亲测可用)

Nginx+Tomcat+Memcached负载均衡配置完整流程: 前言: Nginx实现Tomcat的负载均衡和利用memcached实现session共享. 首先配置tomcat,JDK 将jdk,tomcat 放入站点/opt目录中 安装JDK cd /opt chmod 755 jdk-6u45-linux-x64-rpm.bin ./jdk-6u45-linux-x64-rpm.bin java -version      //检验版本 安装Tomcat tar -zxf apache

Nginx防盗链、Nginx访问控制、Nginx解析php相关配置、Nginx代理

Nginx防盗链 1.[[email protected] test.com]# vi /usr/local/nginx/conf/vhost/test.com.conf #+表示1或者多个,+前面的字符 location ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip|doc|pdf|gz|bz2|jpeg|bmp|xls)$ { expires 7d; valid_referers none blocked server_names  *.test.com ; #定

Nginx的防盗链、Nginx的访问控制、Nginx解析php的配置、Nginx代理

Nginx的防盗链 Nginx的访问控制 禁止上传图片目录里php解析 Nginx解析php的配置 Nginx代理 原文地址:http://blog.51cto.com/13515599/2087315

Nginx防盗链 Nginx访问控制 Nginx解析php相关配置 Nginx代理

12.13 Nginx防盗链cd /usr/local/nginx/conf/vhostvi test.com.conf将以上内容复制到下图位置测试,成功前提data/wwwroot/test.com目录下要有1.gif12.14 Nginx访问控制cd /usr/local/nginx/conf/vhostvi test.com.confFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=" alt="Nginx

49.Nginx防盗链、Nginx访问控制、Nginx解析php相关配置、Nginx代理

一.Nginx防盗链 配置如下,可以和上面的配置结合起来 vim /usr/local/nginx/conf/vhost/test.com.conf location ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip|doc|pdf|gz|bz2|jpeg|bmp|xls)$ //location后面的*是忽略大小写 { expires 7d; valid_referers none blocked server_names *.test.com ; //白名单 if (

四十九、Nginx防盗链、Nginx访问控制、Nginx解析PHP相关配置、Nginx代理

一.Nginx防盗链 必须和"不记录日志和过期时间"结合在一起,因为它们同时用到了location. # vim /usr/local/nginx/conf/vhost/test.com.conf location ~* ^.+\.(gif|jpg|png|bmp|swf|jpeg|flv|rar|zip|doc|pdf|gz|bz2|xls)$ { expires 7d;    过期时间 valid_referers none blocked server_names *.test.

Linux centos VMware Nginx防盗链、Nginx访问控制、Nginx解析php相关配置、Nginx代理

一.Nginx防盗链 配置如下,可以和上面的配置结合起来 location ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip|doc|pdf|gz|bz2|jpeg|bmp|xls)$ { expires 7d; valid_referers none blocked server_names *.test.com ; if ($invalid_referer) { return 403; } access_log off; } 二.Nginx访问控制 需求:访问/adm