[关闭]
@kklinan 2017-02-17T17:35:36.000000Z 字数 5892 阅读 848

Nginx 架构

Nginx


Nginx 的请求处理

Nginx 使用一个多进程模型来对外提供服务,其中一个 master 进程,多个 worker 进程。master 进程负责管
理 Nginx 本身和其他 worker 进程。

所有实际上的业务处理逻辑都在 worker 进程。worker 进程中有一个函数,执行无限循环,不断处理收到的来自客户端的请求,并进行处理,直到整个 Nginx 服务被停止。

worker 进程中,ngx_worker_process_cycle()函数就是这个无限循环的处理函数。在这个函数中,一个请求的简单处理流程如下:

请求的处理流程

为了让大家更好的了解 Nginx 中请求处理过程,我们以 HTTP Request 为例,来做一下详细地说明。
从 Nginx 的内部来看,一个 HTTP Request 的处理过程涉及到以下几个阶段。

在这里,我们需要了解一下 phase handler 这个概念。phase 字面的意思,就是阶段。所以 phase handlers
也就好理解了,就是包含若干个处理阶段的一些 handler。

在每一个阶段,包含有若干个 handler,再处理到某个阶段的时候,依次调用该阶段的 handler 对 HTTP Requ
est 进行处理。

通常情况下,一个 phase handler 对这个 request 进行处理,并产生一些输出。通常 phase handler 是与定义在配置文件中的某个 location 相关联的。

一个 phase handler 通常执行以下几项任务:

当 Nginx 读取到一个 HTTP Request 的 header 的时候,Nginx 首先查找与这个请求关联的虚拟主机的配
置。如果找到了这个虚拟主机的配置,那么通常情况下,这个 HTTP Request 将会经过以下几个阶段的处理(p
hase handlers):

在内容产生阶段,为了给一个 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 依次尝试:

内容产生阶段完成以后,生成的输出会被传递到 filter 模块去进行处理。filter 模块也是与 location 相关的。所有的 fiter 模块都被组织成一条链。输出会依次穿越所有的 filter,直到有一个 filter 模块的返回值表明已经处理完成。

这里列举几个常见的 filter 模块,例如:

在所有的 filter 中,有几个 filter 模块需要关注一下。按照调用的顺序依次说明如下:

Nginx 的配置系统

Nginx 的配置系统由一个主配置文件和其他一些辅助的配置文件构成。这些配置文件均是纯文本文件,全部位于
Nginx 安装目录下的 conf 目录下。

配置文件中以 # 开始的行,或者是前面有若干空格或者 TAB,然后再跟 # 的行,都被认为是注释,也就是只对
编辑查看文件的用户有意义,程序在读取这些注释行的时候,其实际的内容是被忽略的。

由于除主配置文件 nginx.conf以外的文件都是在某些情况下才使用的,而只有主配置文件是在任何情况下都被使用的。所以在这里我们就以主配置文件为例,来解释 Nginx 的配置系统。

在 nginx.conf 中,包含若干配置项。每个配置项由配置指令和指令参数 2 个部分构成。指令参数也就是配置指令对应的配置值。

指令概述

配置指令是一个字符串,可以用单引号或者双引号括起来,也可以不括。但是如果配置指令包含空格,一定要引
起来。

指令参数

指令的参数使用一个或者多个空格或者 TAB 字符与指令分开。指令的参数有一个或者多个 TOKEN 串组成。TO
KEN 串之间由空格或者 TAB 键分隔。

TOKEN 串分为简单字符串或者是复合配置块。复合配置块即是由大括号括起来的一堆内容。一个复合配置块中
可能包含若干其他的配置指令。

如果一个配置指令的参数全部由简单字符串构成,也就是不包含复合配置块,那么我们就说这个配置指令是一个
简单配置项,否则称之为复杂配置项。例如下面这个是一个简单配置项:

error_page 500 502 503 504 /50x.html;

对于简单配置,配置项的结尾使用分号结束。对于复杂配置项,包含多个 TOKEN 串的,一般都是简单 TOKEN
串放在前面,复合配置块一般位于最后,而且其结尾,并不需要再添加分号。例如下面这个复杂配置项:

  1. location / {
  2. root /home/jizhao/nginx-book/build/html;
  3. index index.html index.htm;
  4. }

指令上下文

nginx.conf 中的配置信息,根据其逻辑上的意义,对它们进行了分类,也就是分成了多个作用域,或者称之为配置指令上下文。不同的作用域含有一个或者多个配置项。

当前 Nginx 支持的几个指令上下文:

指令上下文,可能有包含的情况出现。例如:通常 http 上下文和 mail 上下文一定是出现在 main 上下文里
的。在一个上下文里,可能包含另外一种类型的上下文多次。例如:如果 http 服务,支持了多个虚拟主机,那么在 http 上下文里,就会出现多个 server 上下文。

我们来看一个示例配置:

  1. user nobody;
  2. worker_processes 1;
  3. error_log logs/error.log info;
  4. events {
  5. worker_connections 1024;
  6. }
  7. http {
  8. server {
  9. listen 80;
  10. server_name www.linuxidc.com;
  11. access_log logs/linuxidc.access.log main;
  12. location / {
  13. index index.html;
  14. root /var/www/linuxidc.com/htdocs;
  15. }
  16. }
  17. server {
  18. listen 80;
  19. server_name www.Androidj.com;
  20. access_log logs/androidj.access.log main;
  21. location / {
  22. index index.html;
  23. root /var/www/androidj.com/htdocs;
  24. }
  25. }
  26. }
  27. mail {
  28. auth_http 127.0.0.1:80/auth.php;
  29. pop3_capabilities "TOP" "USER";
  30. imap_capabilities "IMAP4rev1" "UIDPLUS";
  31. server {
  32. listen 110;
  33. protocol pop3;
  34. proxy on;
  35. }
  36. server {
  37. listen 25;
  38. protocol smtp;
  39. proxy on;
  40. smtp_auth login plain;
  41. xclient off;
  42. }
  43. }

在这个配置中,上面提到个五种配置指令上下文都存在。
存在于 main 上下文中的配置指令如下:

存在于 http 上下文中的指令如下:

存在于 mail 上下文中的指令如下:

存在于 server 上下文中的配置指令如下:

存在于 location 上下文中的指令如下:

当然,这里只是一些示例。具体有哪些配置指令,以及这些配置指令可以出现在什么样的上下文中,需要参考 Nginx 的使用文档。

Nginx 的模块化体系结构

Nginx 的内部结构是由核心部分和一系列的功能模块所组成。这样划分是为了使得每个模块的功能相对简单,便
于开发,同时也便于对系统进行功能扩展。为了便于描述,下文中我们将使用 Nginx core 来称呼 Nginx 的核心功能部分。

Nginx 提供了 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 模块一般被分成三大类:handler、filter 和 upstream。
Nginx 的模块根据其功能基本上可以分为以下几种类型:

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注