Nginx
{Back to Index}

Table of Contents

1 HTTP 请求处理

1.1 处理请求的 11 个阶段

eleven.png

Table 1: 阶段和对应的模块
Phrase Modules
NGX_HTTP_POST_READ_PHASE realip
NGX_HTTP_SERVER_REWRITE_PHASE rewrite
NGX_HTTP_FIND_CONFIG_PHASE  
NGX_HTTP_REWRITE_PHASE rewrite
NGX_HTTP_POST_REWRITE_PHASE  
NGX_HTTP_PREACCESS_PHASE limit_conn, limit_req
NGX_HTTP_ACCESS_PHASE auth_basic, access, auth_request
NGX_HTTP_POST_ACCESS_PHASE  
NGX_HTTP_TRY_FILES_PHASE try_files, mirrors
NGX_HTTP_CONTENT_PHASE index, random_index, auto_index, concat, static, echo, proxy
NGX_HTTP_LOG_PHASE access_log

如果在某个阶段中,其中一个模块先返回了,则该阶段后续模块不会再处理。

1.1.1 NGX_HTTP_POST_READ_PHASE

该阶段在 Nginx 读取并解析完请求头之后就立即开始运行。

1.1.2 NGX_HTTP_SERVER_REWRITE_PHASE

该阶段执行处于 server 块内,location 块外的重写指令,在读取请求头的过程中 Nginx 会根据 host 及端口找到对应的虚拟主机配置。

1.1.3 NGX_HTTP_FIND_CONFIG_PHASE

该阶段使用重写之后的 uri 来查找对应的 location ,这个阶段并 不支持 Nginx 模块注册处理程序 ,而是由 Nginx 核心来完成当前请求与 location 配置块之间的配对工作。

1.1.4 NGX_HTTP_REWRITE_PHASE

由于 Nginx 已经在 NGX_HTTP_FIND_CONFIG_PHASE 阶段完成了当前请求与 location 的配对,所以从 rewrite 阶段开始,location 配置块中的指令便可以产生作用。

1.1.5 NGX_HTTP_POST_REWRITE_PHASE

location 级别重写的后一阶段,用来检查上阶段是否有 uri 重写,并根据结果跳转到合适的阶段。
这个阶段也 不接受 Nginx 模块注册处理程序 ,而是由 Nginx 核心完成 rewrite 阶段所要求的 内部跳转 操作。
内部跳转 本质上其实就是把当前的请求处理阶段强行倒退到 NGX_HTTP_FIND_CONFIG_PHASE 阶段,以便重新进行请求 URI 与 location 配置块的配对。

1.1.6 NGX_HTTP_PREACCESS_PHASE

该阶段在权限控制阶段之前,一般也用于访问控制,比如限制访问频率,链接数等。

1.1.7 NGX_HTTP_ACCESS_PHASE

让 http 模块判断是否允许这个请求进入 Nginx 服务器,访问权限控制阶段,比如基于 ip 黑白名单的权限控制,基于用户名密码的权限控制等。

1.1.8 NGX_HTTP_POST_ACCESS_PHASE

访问权限控制的后一阶段,该阶段根据权限控制阶段的执行结果进行相应处理,向用户发送拒绝服务的错误码,用来响应上一阶段的拒绝。
不支持 Nginx 模块注册处理程序

1.1.9 NGX_HTTP_TRY_FILES_PHASE

为访问静态文件资源而设置,try_files 指令的处理阶段,如果没有配置 try_files 指令,则该阶段被跳过。

1.1.10 NGX_HTTP_CONTENT_PHASE

处理 http 请求内容的阶段,大部分 http 模块介入这个阶段,内容生成阶段,该阶段产生响应,并发送到客户端。

1.1.11 NGX_HTTP_LOG_PHASE

该阶段记录日志。

1.2 过滤模块的执行顺序

filter-module.png

Figure 2: 11 个阶段之后会执行过滤模块

1.2.1 ngx_http_not_modified_filter_module

1.2.2 ngx_http_range_body_filter_module

1.2.3 ngx_http_copy_filter_module

1.2.4 ngx_http_rds_csv_filter_module

1.2.5 ngx_http_rds_json_filter_module

1.2.6 ngx_http_headers_more_filter_module

1.2.7 ngx_http_lua_filter_module

1.2.8 ngx_http_srcache_filter_module

1.2.9 ngx_http_xss_filter_module

1.2.10 ngx_http_echo_filter_module

1.2.11 ngx_http_headers_filter_module

1.2.12 ngx_http_userid_filter_module

1.2.13 ngx_http_addition_filter_module

在相应前或响应后增加内容,增加内容的方式是 通过 url 响应完成的

1.2.14 ngx_http_sub_filter_module

将响应中指定的字符串替换为新的字符串。

1.2.15 ngx_http_charset_filter_module

1.2.16 ngx_http_ssi_filter_module

1.2.17 ngx_http_postpone_filter_module

1.2.18 ngx_http_gzip_filter_module

1.2.19 ngx_http_range_header_filter_module

1.2.20 ngx_http_v2_filter_module

1.2.21 ngx_http_chunked_filter_module

1.2.22 ngx_http_header_filter_module

1.2.23 ngx_http_write_filter_filter_module

2 模块与指令

2.1 http_core

2.1.1 location

location0.png

Figure 3: 匹配语法

location.png

Figure 4: 匹配逻辑

^~= 都可阻止继续匹配正则,区别在于 ^~ 依然遵循最大前缀匹配规则,而 = 是严格匹配。

2.1.2 satisfy

satisfy.png

2.1.3 try_files

try_files.png

2.1.4 mirror

mirror.png

2.1.5 静态文件处理

2.1.5.1 root/static
  • alias 是一个目录别名的定义,root 则是对上层目录的定义
  • alias 中,如果 location 后面以 / 结束(如:location img ),则 alias 后面也必须要用 /结束; 如果 location 后面不以 / 结束(如:location /img ),则 alias 后面也必须没有。root 没有这样的限制。

root-alias.png

2.1.5.2 相关变量

static-vars.png

2.1.5.3 content-type

content-type.png

2.1.5.4 访问目录重定向问题

dir-redirect.png

dir-redirect-directive.png

Figure 12: 控制重定向用到的指令

2.2 http_realip

realip.png

Figure 13: realip

2.3 http_rewrite

2.3.1 return

return.png

Figure 14: return 指令

2.3.2 error_page

error_page.png

Figure 15: error_page 指令

2.3.3 rewrite

rewrite.png

Figure 16: rewrite 指令

2.3.4 if

if.png

Figure 17: if 指令

2.3.4.1 邪恶的 if

if 块中的配置会在条件为真时,替换当前请求的配置块,当有多个 if 块时,最后一个块才会生效。

2.4 http_limit_conn

limit_conn1.png

limit_conn2.png

limit_conn3.png

2.5 http_limit_req

limit-req1.png

limit-req2.png

  • burst

    这个配置的意思是设置一个大小为 n 的缓冲区当有大量请求(爆发)过来时,超过了访问频次限制的请求可以先放到这个缓冲区内等待,
    但是这个等待区里的位置只有 n 个,超过的请求会直接报 limit_req_status 错误然后返回。

  • nodelay

    如果设置,会在瞬时提供处理 (burst + rate) 个请求的能力,请求超过 (burst + rate) 的时候就会直接返回 limit_req_status ,不存在请求需要等待的情况。 如果没有设置,则所有请求会依次等待排队。

2.6 http_access

access.png

最后一行必须为 deny all

2.7 http_auth_request

auth-req.png

2.8 http_log_module

access-log.png

access-log-file.png

access-log-file-opt.png

Figure 27: 如果日志文件名包含变量,意味着需要经常打开关闭文件,可以使用缓存来提高性能

3 变量

3.1 HTTP 相关

3.1.1 处理请求前使用的变量

http-vars1.png

http-vars-2.png

http-vars3.png

http-vars-4.png

3.1.2 处理请求时产生的变量

http-req-vars-1.png

http-req-vars-2.png

3.1.3 发送响应时使用的变量

http-resp-vars.png

3.2 TCP 相关

tcp-vars-1.png

tcp-vars-2.png

3.3 Nginx 系统变量

nginx-vars.png

3.4 动态创建变量

3.4.1 map

map-prin.png

Figure 38: 原理

map-directive.png

Figure 39: map 指令

map-rule.png

Figure 40: 规则

3.4.2 split_clients

split-prin.png

split-dir.png

4 反向代理

reverse-proxy.png

4.1 指定上游服务器地址

upstream.png

upstream2.png

upstream-keepalive.png

4.2 负载均衡

4.2.1 Round Robin

upstream-round-robin.png

4.2.2 IP Hash

ip-hash.png

4.2.3 对任意关键字 Hash

any-hash.png

4.2.4 一致性哈希算法

hash-problem.png

Figure 50: 普通哈希算法的问题

con-hash-before.pngj

con-hash-after.png

开启一致性哈希算法,只需在 hash 指令后加上 consistent 即可。

hash-con.png

4.3 upstream 提供的变量

upstream-vars-without-cache.png

upstream-vars-without-cache2.png

4.4 反向代理流程

reverse-proxy-procedure.png

Figure 55: HTTP 反向代理流程

4.4.1 proxy_pass

proxy-pass.png

Figure 56: proxy_pass 参数规则

4.4.2 生成发往上游的信息

4.4.2.1 生成请求行
Syntax: proxy_method <method>;
Default: -
Context: http, server, location


Syntax: proxy_http_version 1.0|1.1;
Default: proxy_http_version 1.0;
Context: http, server, location
4.4.2.2 生成请求头部
Syntax: proxy_set_header <field> <value>; # 如果 value 值为空,则整个 header 都不会向上发送
Default: proxy_set_header Host $proxy_host; proxy_set_header Connection close;
Context: http, server, location


Syntax: proxy_pass_request_headers on|off;
Default: proxy_pass_request_headers on;
Context: http, server, location
4.4.2.3 生成请求包体
Syntax: proxy_pass_request_body on|off;
Default: proxy_pass_request_body on;
Context: http, server, location

Syntax: proxy_set_body <value>;
Default: -
Context: http, server, location

4.4.3 proxy_request_buffering

proxy_request_buffering.png

Figure 57: 控制收完再转发还是边收边转发

5 stream

stream-7-phase.png

5.1 上下游限速

proxy_rate.png

Figure 59: 图中黑色箭头部分不提供限速指令(因为可以忽略 Nginx 对转发的影响,即红色箭头限速了,黑色箭头也就限速了)

Author: Hao Ruan (ruanhao1116@gmail.com)

Created: 2020-11-19 Thu 14:19

Updated: 2021-08-17 Tue 11:23

Emacs 27.1 (Org mode 9.3)