转:NGNIX模块开发——nginx的配置系统
From:http://tengine.taobao.org/book/chapter_02.html
nginx的配置系统
nginx的配置系统由一个主配置文件和其他一些辅助的配置文件构成。这些配置文件均是纯文本文件,全部位于nginx安装目录下的conf目录下。
配置文件中以#开始的行,或者是前面有若干空格或者TAB,然后再跟#的行,都被认为是注释,也就是只对编辑查看文件的用户有意义,程序在读取这些注释行的时候,其实际的内容是被忽略的。
由于除主配置文件nginx.conf以外的文件都是在某些情况下才使用的,而只有主配置文件是在任何情况下都被使用的。所以在这里我们就以主配置文件为例,来解释nginx的配置系统。
在nginx.conf中,包含若干配置项。每个配置项由配置指令和指令参数2个部分构成。指令参数也就是配置指令对应的配置值。
指令概述
配置指令是一个字符串,可以用单引号或者双引号括起来,也可以不括。但是如果配置指令包含空格,一定要引起来。
指令参数
指令的参数使用一个或者多个空格或者TAB字符与指令分开。指令的参数有一个或者多个TOKEN串组成。TOKEN串之间由空格或者TAB键分隔。
TOKEN串分为简单字符串或者是复合配置块。复合配置块即是由大括号括起来的一堆内容。一个复合配置块中可能包含若干其他的配置指令。
如果一个配置指令的参数全部由简单字符串构成,也就是不包含复合配置块,那么我们就说这个配置指令是一个简单配置项,否则称之为复杂配置项。例如下面这个是一个简单配置项:
error_page /50x.html;
对于简单配置,配置项的结尾使用分号结束。对于复杂配置项,包含多个TOKEN串的,一般都是简单TOKEN串放在前面,复合配置块一般位于最后,而且其结尾,并不需要再添加分号。例如下面这个复杂配置项:
location / {
    root   /home/jizhao/nginx-book/build/html;
    index  index.html index.htm;
}
指令上下文
nginx.conf中的配置信息,根据其逻辑上的意义,对它们进行了分类,也就是分成了多个作用域,或者称之为配置指令上下文。不同的作用域含有一个或者多个配置项。当前nginx支持的几个指令上下文:
| main: | nginx在运行是与具体业务功能(比如http服务或者email服务代理)无关的一些参数,比如工作进程数,运行的身份等。 | 
|---|---|
| http: | 与提供http服务相关的一些配置参数。例如:是否使用keepalive啊,是否使用gzip进行压缩等。 | 
| server: | http服务上支持若干虚拟主机。每个虚拟主机一个对应的server配置项,配置项里面包含该虚拟主机相关的配置。在提供mail服务的代理时,也可以建立如果server.每个server通过监听的地址来区分。 | 
| location: | http服务中,某些特定的URL对应的一系列配置项。 | 
| mail: | 实现email相关的SMTP/IMAP/POP3代理时,共享的一些配置项(因为可能实现多个代理,工作在多个监听地址上)。 | 
指令上下文,可能有包含的情况出现。例如:通常http上下文和mail上下文一定是出现在main上下文里的。在一个上下文里,可能包含另外一种类型的上下文多次。例如:如果http服务,支持了多个虚拟主机,那么在http上下文里,就会出现多个server上下文。我们来看一个示例配置:
user nobody;
worker_processes ;
error_log logs/error.log info; events {
worker_connections ;
} http {
server {
listen ;
server_name www.linuxidc.com;
access_log logs/linuxidc.access.log main;
location / {
index index.html;
root /var/www/linuxidc.com/htdocs;
}
} server {
listen ;
server_name www.Androidj.com;
access_log logs/androidj.access.log main;
location / {
index index.html;
root /var/www/androidj.com/htdocs;
}
}
} mail {
auth_http 127.0.0.1:/auth.php;
pop3_capabilities "TOP" "USER";
imap_capabilities "IMAP4rev1" "UIDPLUS"; server {
listen ;
protocol pop3;
proxy on;
}
server {
listen ;
protocol smtp;
proxy on;
smtp_auth login plain;
xclient off;
}
}
在这个配置中,上面提到个五种配置指令上下文都存在。
存在于main上下文中的配置指令如下:
- user
 - worker_processes
 - error_log
 - events
 - http
 
存在于http上下文中的指令如下:
- server
 
存在于mail上下文中的指令如下:
- server
 - auth_http
 - imap_capabilities
 
存在于server上下文中的配置指令如下:
- listen
 - server_name
 - access_log
 - location
 - protocol
 - proxy
 - smtp_auth
 - xclient
 
存在于location上下文中的指令如下:
- index
 - root
 
当然,这里只是一些示例。具体有哪些配置指令,以及这些配置指令可以出现在什么样的上下文中,需要参考nginx的使用文档。
nginx的模块化体系结构
nginx的内部结构是由核心部分和一系列的功能模块所组成。这样划分是为了使得每个模块的功能相对简单,便于开发,同时也便于对系统进行功能扩展。为了便于描述,下文中我们将使用nginx core来称呼nginx的核心功能部分。nginx core提供了web服务器的基础功能,同时提供了web服务反向代理,email服务反向代理功能。nginx core实现了底层的通讯协议,为其他模块和nginx进程构建了基本的运行时环境,并且构建了其他各模块的协作基础。除此之外,或者说大部分与协议相关的,或者应用相关的功能都是在这些模块中所实现的。
模块概述
nginx将各功能模块组织成一条链,当有请求到达的时候,请求依次经过这条链上的部分或者全部模块,进行处理。每个模块实现特定的功能。例如,实现对请求解压缩的模块,实现SSI的模块,实现与上游服务器进行通讯的模块,实现与FastCGI服务进行通讯的模块。有两个模块比较特殊,他们居于nginx core和各功能模块的中间。这两个模块就是http模块和mail模块。这2个模块在nginx core之上实现了另外一层抽象,处理与HTTP协议和email相关协议(SMTP/POP3/IMAP)有关的事件,并且确保这些事件能被以正确的顺序调用其他的一些功能模块。目前HTTP协议是被实现在http模块中的,但是有可能将来被剥离到一个单独的模块中,以扩展nginx支持SPDY协议。
模块的分类
nginx的模块根据其功能基本上可以分为以下几种类型:
| event module: | 搭建了独立于操作系统的事件处理机制的框架,及提供了各具体事件的处理。包括ngx_events_module, ngx_event_core_module和ngx_epoll_module等。nginx具体使用何种事件处理模块,这依赖于具体的操作系统和编译选项。 | 
|---|---|
| phase handler: | 此类型的模块也被直接称为handler模块。主要负责处理客户端请求并产生待响应内容,比如ngx_http_static_module模块,负责客户端的静态页面请求处理并将对应的磁盘文件准备为响应内容输出。 | 
| output filter: | 也称为filter模块,主要是负责对输出的内容进行处理,可以对输出进行修改。例如,可以实现对输出的所有html也面增加预定义的footbar一类的工作,或者对输出的图片的URL进行替换之类的工作。 | 
| upstream: | upstream模块实现反向代理的功能,将真正的请求转发到后端服务器上,并从后端服务器上读取响应,发回客户端。upstream模块是一种特殊的handler,只不过响应内容不是真正有自己产生的,而是从后端服务器上读取的。 | 
| load-balancer: | 负载均衡模块,实现特定的算法,在众多的后端服务器中,选择一个服务器出来作为某个请求的转发服务器。 | 
nginx的请求处理
nginx使用一个多进程模型来对外提供服务,其中一个master进程,多个worker进程。master进程负责管理nginx本身和其他worker进程。所有实际上的业务处理逻辑都在worker进程。worker进程中有一个函数,执行无限循环,不断处理收到的来自客户端的请求,并进行处理,直到整个nginx服务被停止。worker进程中,ngx_worker_process_cycle()函数就是这个无限循环的处理函数。在这个函数中,一个请求的简单处理流程如下:
- 操作系统提供的机制(例如epoll, kqueue等)产生相关的事件。
 - 接收和处理这些事件,如是接受到数据,则产生更高层的request对象。
 - 处理request的header和body。
 - 产生响应,并发送回客户端。
 - 完成request的处理。
 - 重新初始化定时器及其他事件。
 
请求的处理流程
为了让大家更好的了解nginx中请求处理过程,我们以HTTP Request为例,来做一下详细地说明。从nginx的内部来看,一个HTTP Request的处理过程涉及到一下几个阶段。
- 初始化HTTP Request(读取来自客户端的数据,生成HTTP Requst对象,该对象含有该请求所有的信息)。
 - 处理请求头。
 - 处理请求体。
 - 如果有的话,调用与此请求(URL或者Location)关联的handler
 - 依次调用各phase handler进行处理。
 
在这里,我们需要了解一下phase handler这个概念。phase字面的意思,就是阶段。所以phase handlers也就好理解了,就是包含若干个处理阶段的一些handler。在每一个阶段,包含有若干个handler,再处理到某个阶段的时候,依次调用该阶段的handler对HTTP Request进行处理。通常情况下,一个phase handler对这个request进行处理,并产生一些输出。通常phase handler是与定义在配置文件中的某个location相关联的。一个phase handler通常执行以下几项任务:
- 获取location配置
 - 产生适当的响应
 - 发送response header
 - 发送response body
 
当nginx读取到一个HTTP Request的header的时候,nginx首先查找与这个请求关联的虚拟主机的配置。如果找到了这个虚拟主机的配置,那么通常情况下,这个HTTP Request将会经过以下几个阶段的处理(phase handlers):
| NGX_HTTP_POST_READ_PHASE: | 读取请求内容阶段 | 
| NGX_HTTP_SERVER_REWRITE_PHASE: | Server请求地址重写阶段 | 
| NGX_HTTP_FIND_CONFIG_PHASE: | 配置查找阶段: | 
| NGX_HTTP_REWRITE_PHASE: | Location请求地址重写阶段 | 
| NGX_HTTP_POST_REWRITE_PHASE: | 请求地址重写提交阶段 | 
| NGX_HTTP_PREACCESS_PHASE: | 访问权限检查准备阶段 | 
| NGX_HTTP_ACCESS_PHASE: | 访问权限检查阶段 | 
| NGX_HTTP_POST_ACCESS_PHASE: | 访问权限检查提交阶段 | 
| NGX_HTTP_TRY_FILES_PHASE: | 配置项try_files处理阶段 | 
| NGX_HTTP_CONTENT_PHASE: | 内容产生阶段 | 
| NGX_HTTP_LOG_PHASE: | 日志模块处理阶段 | 
在内容产生阶段,为了给一个request产生正确的响应,nginx必须把这个request交给一个合适的content handler去处理。如果这个request对应的location在配置文件中被明确指定了一个content handler,那么nginx就可以通过对location的匹配,直接找到这个对应的handler,并把这个request交给这个content handler去处理。这样的配置指令包括像,perl,flv,proxy_pass,mp4等。如果一个request对应的location并没有直接有配置的content handler,那么nginx依次尝试:
- 如果一个location里面有配置 random_index on,那么随机选择一个文件,发送给客户端。
 - 如果一个location里面有配置 index指令,那么发送index指令指名的文件,给客户端。
 - 如果一个location里面有配置 autoindex on,那么就发送请求地址对应的服务端路径下的文件列表给客户端。
 - 如果这个request对应的location上有设置gzip_static on,那么就查找是否有对应的.gz文件存在,有的话,就发送这个给客户端(客户端支持gzip的情况下)。
 - 请求的URI如果对应一个静态文件,static module就发送静态文件的内容到客户端。
 
内容产生阶段完成以后,生成的输出会被传递到filter模块去进行处理。filter模块也是与location相关的。所有的fiter模块都被组织成一条链。输出会依次穿越所有的filter,直到有一个filter模块的返回值表明已经处理完成。
这里列举几个常见的filter模块,例如: #) server-side includes。 #) XSLT filtering。 #) 图像缩放之类的。 #) gzip压缩。
在所有的filter中,有几个filter模块需要关注一下。按照调用的顺序依次说明如下:
| write: | 写输出到客户端,实际上是写到连接对应的socket上。 | 
|---|---|
| postpone: | 这个filter是负责subrequest的,也就是子请求的。 | 
| copy: | 将一些需要复制的buf(文件或者内存)重新复制一份然后交给剩余的body filter处理。 | 
转:NGNIX模块开发——nginx的配置系统的更多相关文章
- nginx的配置系统
		
nginx的配置系统由一个主配置文件和其他一些辅助的配置文件构成.这些配置文件均是纯文本文件,全部位于nginx安装目录下的conf目录下. 配置文件中以#开始的行,或者是前面有若干空格或者TAB,然 ...
 - Nginx模块开发-理解HTTP配置
		
理解HTTP配置 相关数据结构 先明白Nginx下述数据结构,再理解 HTTP配置的解析与合并过程 ngx_module_t 官方API typedef struct{ NGX_MODULE_V1; ...
 - 配置rt-thread开发环境(配置系统,生成系统镜像)
		
配置rt-thread开发环境 ===========Python============= 1.Python的下载地址:http://www.python.org/ftp/python/ 链接中有各 ...
 - nginx模块开发篇 (阿里著作)
		
背景介绍 nginx历史 使用简介 nginx特点介绍 nginx平台初探(100%) 初探nginx架构(100%) nginx基础概念(100%) connection request 基本数据结 ...
 - Nginx访问限制模块limit_conn_zone 和limit_req_zone配置使用
		
nginx可以通过limit_conn_zone 和limit_req_zone两个组件来对客户端访问目录和文件的访问频率和次数进行限制,另外还可以善用进行服务安全加固,两个模块都能够对客户端访问进行 ...
 - linux下nginx模块开发入门
		
本文模块编写参考http://blog.codinglabs.org/articles/intro-of-nginx-module-development.html 之前讲了nginx的安装,算是对n ...
 - 【转】Nginx模块开发入门
		
转自: http://kb.cnblogs.com/page/98352/ 结论:对Nginx模块开发入门做了一个helloworld的示例,简单易懂.也有一定的深度.值得一看. Nginx模块开发入 ...
 - Nginx模块开发入门
		
前言 Nginx是当前最流行的HTTP Server之一,根据W3Techs的统计,目前世界排名(根据Alexa)前100万的网站中,Nginx的占有率为6.8%.与Apache相比,Nginx在高并 ...
 - 开发Nginx模块
		
开发Nginx模块 前面的哪些话 关于Nginx模块开发的博客资料,网上很多,很多.但是,每篇博客都只提要点,无法"step by step"照着做,对于初次接触Nginx开发的同 ...
 
随机推荐
- Eclipse 进入代码定位文件位置
 - 血族第四季/全集The Strain迅雷下载
			
当第四季开始时,故事时间已经过去九个月.世界陷入黑暗,斯特里高伊吸血鬼控制了一切.第三季结尾的爆炸引发了一场全球核灾难,核冬天的到来令地表变得暗无天日,斯特里高伊获得解放.它们大白天也能出来活动,帮助 ...
 - Android组件化方案
			
Android组件化项目地址:Android组件化项目AndroidModulePattern Android组件化之终极方案地址:http://blog.csdn.net/guiying712/ar ...
 - 获取机器的基本参数cat /proc/stat
			
获取机器的基本参数cat /proc/stat Note : This guide is applicable to Linux kernels 2.6.14 and above, which add ...
 - 【电信我想问一下,网页上多出的隐藏广告】究竟谁在耍流氓,还要不要脸了??? 0817tt 植入广告
			
最近总是有网页 莫名的有声音,是网页游戏的,一刷新就没了. 这次 我怒了! 我觉得不可能是这个网站的chinaunix的广告.左边是 有广告的,右侧标签 是无广告的. 有广告的 实际上 隐藏了一个页面 ...
 - jQuery easyui layout布局自适应浏览器大小(转)
			
首先解释一下标题的含义,当我们用jQuery easyui layout 进行布局的时候,可能会遇到这样一个问题,那就是当手工调整浏览器大小,或者最大化.还原窗口的时候,layout的某个区域不能填充 ...
 - RV LayoutManager 流式布局 MD
			
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
 - Android模仿三星手机系统滑动条滑动时滑块变大的特效
			
使用三星手机的过程中发现三星手机系统自带的滑动条有一个特效.比方调节亮度的滑动条.在滑动滑块的过程中,滑块会变大.功能非常小可是体验却非常好,于是决定做一个这种效果出来.好了废话不多说了,以下開始实现 ...
 - VS2013开发asmx接口返回一个自定义XML
			
1:利用XmlDocument生成一个xml文档返回,代码如下 using System;using System.Collections.Generic;using System.Linq;usin ...
 - VS2013创建Node.js C++ Addons的过程
			
首先看我的Node.js版本. node –v v6.11.4 然后参照这篇文章来做: https://nodejs.org/api/addons.html#addons_hello_world 安装 ...