Nginx核心配置详解
导航: 这里将Nginx的一些配置进行整合。根据导航比较容易找到对应的文档。资料来自于weixueyuan 5.Nginx 缓存 |
作为一款高性能的 HTTP 服务器软件,Nginx 的核心功能就是应对 HTTP 请求的处理。由于具体硬件、操作系统及应用场景的不同,需要 Nginx 在对 HTTP 请求的处理方法上进行不同的调整,为了应对这些差异,Nginx 提供了多种配置指令,让用户可以根据实际的软硬件及使用场景进行灵活配置。
为了方便理解和使用,可以按照其在代码中的分布,将其分为核心配置指令和模块配置指令两大类。核心配置指令分为事件核心配置指令和 HTTP 核心配置指令,事件核心配置指令主要是与 Nginx 自身软件运行管理及 Nginx 事件驱动架构有关的配置指令;HTTP 核心配置指令是对客户端从发起 HTTP 请求、完成 HTTP 请求处理、返回处理结果,到关闭 HTTP 连接的完整过程中的各个处理方法进行配置的配置指令。模块配置指令是在每个 Nginx 模块中对所在模块的操作方法进行配置的配置指令。
1.Nginx配置文件详解
Nginx使用yum安装后,配置文件会保存在/etc/nginx/nginx.conf,在配置文件目录下,Nginx 默认的主配置文件是 nginx.conf,这也是 Nginx 唯一的默认配置入口
1.配置文件目录
Nginx 配置文件在 conf 目录下,其默认目录结构如下。
conf/ ├── fastcgi.conf ├── fastcgi.conf.default ├── fastcgi_params ├── fastcgi_params.default ├── koi-utf ├── koi-win ├── mime.types ├── mime.types.default ├── nginx.conf ├── nginx.conf.default ├── scgi_params ├── scgi_params.default ├── uwsgi_params ├── uwsgi_params.default └── win-utf
其中,以“.default”为扩展名的文件是 Nginx 配置文件的配置样例文件。各配置文件的说明如下。
-
- fastcgi_params:Nginx 在配置 FastCGI 代理服务时会根据 fastcgi_params 文件的配置向 FastCGI 服务器传递变量,该配置文件现已由 fastcgi.conf 代替;
- fastcgi.conf:为了规范配置指令 SCRIPT_FILENAME 的用法,引入 FastCGI 变量传递配置;
- mime.types:MIME 类型映射表,Nginx 会根据服务端文件后缀名在映射关系中获取所属文件类型,将文件类型添加到 HTTP 消息头字段“Content-Type”中;
- nginx.conf:Nginx 默认的配置入口文件;
- scgi_params:Nginx 在配置 SCGI 代理服务时会根据 scgi_params 文件的配置向 SCGI 服务器传递变量;
- uwsgi_params:Nginx 在配置 uWSGI 代理服务时会根据 uwsgi_params 文件的配置向 uWSGI 服务器传递变量;
- koi-utf、koi-win、win-utf:这 3 个文件是 KOI8-R 编码转换的映射文件,因为 Nginx 的作者是俄罗斯人,在 Unicode 流行之前,KOI8-R 是使用最为广泛的俄语编码。
2.配置文件结构
为了便于了解 Nginx 配置文件的内部结构,这里约定几个名词的定义。
1) 配置指令
在配置文件中,由 Nginx 约定的内部固定字符串,Nginx 官方文档中的英文单词为 directive,本教程中则统一称为配置指令,简称指令。指令是 Nginx 中功能配置的最基本元素,Nginx 的每个功能配置都是通过多个不同的指令组合来实现的。
2) 配置指令值
每个配置指令都有对应的内容来表示该指令的控制参数,本教程中约定其对应的内容为配置指令值,简称指令值。指令值可以是字符串、数字或变量等多种类型。
3) 配置指令语句
指令与指令值组合构成指令语句。一条指令语句可以包含多个配置指令值,在 Nginx 配置文件中,每条指令语句都要用;作为语句结束的标识符。
4) 配置指令域
配置指令值有时会是由{ }括起来的指令语句集合,本教程中约定{ }括起来的部分为配置指令域,简称指令域。指令域既可以包含多个指令语句,也可以包含多个指令域。
5) 配置全局域
配置文件 nginx.conf 中上层没有其他指令域的区域被称为配置全局域,简称全局域。
Nginx 的常见配置指令域如下表所示。
域名称 | 域类型 | 域说明 |
main | 全局域 | Nginx 的根级别指令区域。该区域的配置指令是全局有效的,该指令名为隐性显示,nginx.conf 的整个文件内容都写在该指令域中 |
events | 指令域 | Nginx 事件驱动相关的配置指令域 |
http | 指令域 | Nginx HTTP 核心配置指令域,包含客户端完整 HTTP 请求过程中每个过程的处理方法的配置指令 |
upstream | 指令域 | 用于定义被代理服务器组的指令区域,也称“上游服务器” |
server | 指令域 | Nginx 用来定义服务 IP、绑定端口及服务相关的指令区域 |
location | 指令域 | 对用户 URI 进行访问路由处理的指令区域 |
stream | 指令域 | Nginx 对 TCP 协议实现代理的配置指令域 |
types | 指令域 | 定义被请求文件扩展名与 MIME 类型映射表的指令区域 |
if | 指令域 | 按照选择条件判断为真时使用的配置指令域 |
打开系统默认的 nginx.conf 文件,可以看到整个文件的结构如下。
#user nobody; worker_processes 1; # 只启动一个工作进程 events { worker_connections 1024; # 每个工作进程的最大连接为1024 } http { include mime.types; # 引入MIME类型映射表文件 default_type application/octet-stream; # 全局默认映射类型为application/octet-stream #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent” "$http_x_forwarded_for"'; #access_log logs/access.log main; sendfile on; # 启用零复制机制 keepalive_timeout 65; # 保持连接超时时间为65s server { listen 80; # 监听80端口的网络连接请求 server_name localhost; # 虚拟主机名为localhost #charset koi8-r; #access_log logs/host.access.log main; location / { root html; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
由上述配置文件可以看出,配置文件中的指令和指令值是以类似于 key-value 的形式书写的。写在配置文件全局域的指令是 Nginx 配置文件的核心指令,主要是对 Nginx 自身软件运行进行配置的指令。其中,events 和 http 所包含的部分分别为事件指令域和 HTTP 指令域,指令域内的指令则明确约定了该区域内的指令的应用范围。
server 指令域被包含于 http 指令域中,同时又包含了 location 指令域,各指令域中的共用范围逐层被上层指令域限定,可见各指令域匹配的顺序是由外到内的。Nginx 的配置指令按照内部设定可以同时编写在不同指令域中,包含在最内层的指令将对外层同名指令进行指令值覆盖,并以最内层指令配置为最终生效配置。
编写 Nginx 配置文件时,为了便于维护,也会把一些指令或指令域写在外部文件中,再通过 include 指令引入 nginx.conf 主配置文件中。例如,配置文件中把写有 types 指令域的 mime.types 文件引用到 http 指令域中。此处使用的是 nginx.conf 文件的相对路径。
3.配置文件中的计量单位
在 Nginx 配置文件中有很多与容量、时间相关的指令值,Nginx 配置文件有如下规范。
1) 容量单位可以使用字节、千字节、兆字节或千兆字节,示例如下。
512
1k或1K
10m或10M
1g或10G
2) 时间的最小单位是毫秒,示例如下。
10ms # 10毫秒 30s # 30秒 2m # 2分钟 5h # 5小时 1h 30m # 1小时30分 6d # 6天 3w # 3周 5M # 5个月 2y # 2年
4.配置文件中的哈希表
Nginx 使用哈希表加速对 Nginx 配置中常量的处理,如 server 中的主机名、types 中的 MIME 类型映射表、请求头属性字段等数据集合。哈希表是通过关键码来快速访问常量对应值的数据存储结构,在通过哈希表获取数据的过程中,其内部实现通过相关函数将常量名转换为一个关键码来实现对应值的快速定位和读取。
由于数据的复杂性,会出现不同常量名转换的关键码是一样的情况,这就会导致读取对应值时发生冲突。为了解决这个问题,Nginx 同时引入了哈希桶机制,就是把相同关键码的哈希键存在一个哈希桶定义的存储空间中,然后再进行二次计算来获取对应的值。
单个哈希桶的大小等于 CPU 缓存行大小的倍数。这样就可以通过减少内存访问的数量来加速在 CPU 中搜索哈希关键码的速度。如果哈希桶的大小等于 CPU 的缓存行的大小,在 Nginx 进行哈希关键码搜索期间,内存的访问次数最多是两次,一次是计算哈希桶的地址,另一次是在哈希桶内进行哈希关键码的搜索。
Linux 系统下查看 CPU 缓存行的指令如下。
cat /proc/cpuinfo |grep cache_alignment
Nginx 在每次启动或重新加载配置时会选择合适大小的最小初始化哈希表。哈希表的大小会随哈希桶数量的增加而不断调整,直到哈希桶总的大小达到哈希表设置的最大值。因此,在 Nginx 提示需要增加哈希表或哈希桶的大小时,要先调整哈希表的大小。
2.Nginx进程配置指令详解
Nginx 的进程配置指令包含在 Nginx 核心代码及事件模块代码中,按配置指令设定的功能可分为进程管理、进程调优、进程调试、事件处理 4 个部分。
1.进程管理
Nginx 本身是一款应用软件,在其运行时,用户可对其运行方式、动态加载模块、日志输出等使用其内建的基础配置指令进行配置,指令说明如下表所示。
表:进程管理指令 | ||
指令 | 默认值 | 指令说明 |
daemon | on | 用于设定 Nginx 进程是否以守护进程的方式在后台运行,on 为启用,off 为不启用 |
pid | logs/nginx.pid | 设定保存 Nginx 主进程 ID 的文件路径 |
user | nobody nobody | 用于设定 Nginx 启动后,主进程唤起的工作进程运行的用户及用户组 |
load_module | -- | 加载动态模块的指令 |
include | -- | 加载外部配置文件 |
error_log | logs/error.log error | 指定错误日志文件路径及文件名 |
pcre_jit | off | 用于设定在配置文件中的正则表达式是否使用 pcre_jit 技术,off 为不使用,on 为使用 |
ssl_engine | -- | 指定使用的 OpenSSL 加速引擎名称 |
其中,pcre_jit 需要 Nginx 在配置编译时加上 --with-pcre-jit 参数;error_log 的日志级别可以为如下值:debug、info、notice、warn、error、crit、alert、emerg。
在 Linux 系统中,可用如下命令查看当前系统支持的 OpenSSL 加速引擎信息。
openssl engine -t
2.进程调优
Nginx 是按照事件驱动架构设计的。每个外部请求都以事件的形式被工作进程(Worker Process)响应,并发完成各种功能的操作处理。Nginx 工作进程的性能依赖于硬件和操作系统的配置,在实际应用场景中,用户需要按照硬件、操作系统或应用场景需求的侧重点进行相应的配置调整。
Nginx 的进程调优配置指令如下面表格中所示。
表:线程池指令 | |
名 称 | 线程池指令 |
指令 | thread_pool |
作用域 | main |
默认值 | thread_pool default threads=32 max_queue=65536; |
指令说明 |
线程池配置指令,允许调整默认线程池或创建新的线程池,用于读取和发送文件的场景中。在线程池中所有线程都 繁忙时,新的请求任务将在队列中等待,默认情况下,等待队列中的最大任务数是 65536,使用线程池机制时,通 过配置该指令,可以在因读取和发送文件引发阻塞的场景中提升 Nginx 读取和发送文件的处理性能 |
配置样例如下:
thread_pool pool_1 threads=16;
具体参数说明如下。
-
- thread_pool 也可以编写在 http 指令域中;
- threads 参数定义了线程池的线程数;
- max_queue 参数指定了等待队列中的最大任务数,在线程池中所有线程都处于繁忙状态时,新任务将进入等待队列。等待队列中的最大任务数为 65536;
- 线程池指令需要在编译配置时增加 --with-threads 参数。
表:定时器方案指令 | |
名 称 | 定时器方案指令 |
指令 | timer_resolution |
作用域 | main |
默认值 | -- |
指令说明 |
Nginx 中的处理事件超时管理方案有两种,一种是设定一个定时器,每过一段时间就对所有超时事件进行一次扫描; 另一种是先计算出距离当前时间最近的将要发生超时事件的时间,然后等待这个时间之后再去进行一次超时检测。 默认配置下使用第二种超时检测方案,该方案是依据事件超时时间与当前时间的时间差进行检测的,所以每次事件 返回都需要进行新的检测时间计算,在 I/O 事件比较多的场景下,这会导致频繁地调用时间函数 gettimeofday 进行计算并更新下次检测的时间,资源消耗相对较高。而设置一个指定的时间值启用第一种方案时,Nginx 内置的 事件超时检测定时器会在指定时间周期内进行事件超时检测,无须调用时间函数 gettimeofday 更新时间,资源消耗 相对较低 |
配置样例如下:
timer_resolution 100ms;
在因频繁调用时间函数引发的资源消耗不大的场景中可不设定该指令。
表:工作进程优先级指令 | |
名 称 | 工作进程优先级指令 |
指令 | worker_priority |
作用域 | main |
默认值 | 0 |
指令说明 | 工作进程优先级设定指令,可以通过该指令设定工作进程在 Linux 系统中的优先级(nice 值) |
配置样例如下:
worker_priority -5;
worker_priority 指令值的取值范围是 -20~19,数值越小,优先级越高,获得的 CPU 时间就越多。配置生效后可以通过如下命令查看,输出结果如下图所示。
ps axo command,pid,ni | grep nginx | grep -v grep
表:工作进程数指令 | |
名 称 | 工作进程数指令 |
指令 | worker_processes |
作用域 | main |
默认值 | 1 |
可配置选项 | number 或 auto |
指令说明 |
依据 Nginx 架构可知,工作进程数量的最佳配置是小于或等于 CPU 内核的数量。 通过该指令可以手动设置工作进程的数量,该指令也支持 auto 指令值,由 Nginx 进行自动分配 |
配置样例如下:
worker_processes auto;
工作进程数指令的指令值有两种类型,分别为数字和 auto。指令值为 auto 时,Nginx 会根据 CPU 的内核数生成等数量的工作进程。
表:工作进程 CPU 绑定指令 | |
名 称 | 工作进程 CPU 绑定指令 |
指令 | worker_cpu_affinity |
作用域 | main |
默认值 | -- |
可配置选项 | cpumark 或 auto |
指令说明 |
Nginx 工作进程处于高效的工作状态是因为充分利用了进程与 CPU 的亲缘性,使每个工作进程均可固定在一个 CPU 上运行。 该指令可以手动进行工作进程与 CPU 的绑定,当然也可以通过设定指令值 auto 交由 Nginx 自动分配 |
配置样例如下:
worker_processes 8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
指令值是用 CPU 掩码来表示的,使用与 CPU 数量相等位数的二进制值来表示。单个 CPU 用单个二进制值表示,多个 CPU 组合可用二进制值相加来表示。如配置样例所示,CPU 有 8 个核,分别表示绑定了从第 0 核到第 7 核的 CPU。CPU 核数是从 0 开始计数的。
指令值除了可以是 CPU 掩码外,还可以是 auto。当指令值为 auto 时,Nginx 会自动进行 CPU 绑定。
配置样例如下:
worker_processes auto;
worker_cpu_affinity auto;
工作进程与 CPU 核数也可以是多种对应组合,指令语句如下:
worker_processes 4; worker_cpu_affinity 01 10 01 10; # 表示把第1、3工作进程绑定在2核CPU的第0核,第2、4工作 # 进程绑定在2核CPU的第1核 worker_processes 2; worker_cpu_affinity 0101 1010; # 表示把第1工作进程绑定在CPU的第0核和第2核,第2工作进程 # 绑定在CPU的第1核和第3核
工作进程 CPU 绑定指令仅适合于 FreeBSD 和 Linux 操作系统。
表:工作进程开文件数指令 | |
名 称 | 工作进程开文件数指令 |
指令 | worker_rlimit_nofile |
作用域 | main |
默认值 | -- |
指令说明 | 设置 Nginx 所有工作进程同时打开文件的最大数量,默认为操作系统的文件打开数 |
配置样例如下:
worker_rlimit_nofile 65535;
表:工作进程关闭等待时间指令 | |
名 称 | 工作进程关闭等待时间指令 |
指令 | worker_shutdown_timeout |
作用域 | main |
默认值 | -- |
指令说明 | 设置 Nginx 正常关闭工作进程的超时时间,当超过设定的时间时,Nginx 主进程将强制关闭所有 |
配置样例如下:
worker_shutdown_timeout 10s;
表:设置互斥锁文件指令 | |
名 称 | 设置互斥锁文件指令 |
指令 | lock_file |
作用域 | main |
默认值 | logs/nginx.lock; |
指令说明 |
设置互斥锁文件指令,在开启 accept mutex 进程调度模式或使用共享内存的场景下,需要用到互斥锁机制。 在一些支持原子操作的操作系统中,可使用共享内存实现互斥锁。在不支持原子操作的系统环境下,需要通过 该指令指定一个互斥锁文件 |
配置样例如下:
lock_file logs/nginx.lock;
3.进程调试
Nginx 调整配置或运行发生异常时,为了及时获知工作进程在事件处理过程中发生的问题,可通过获取内存中各状态机、变量等数据的内容进行调试。Nginx 为用户提供了一些调试用的配置指令,方便用户进行进程调试。配置指令如下面表格中所示。
表:主进程指令 | |
名 称 | 主进程指令 |
指令 | master_process |
作用域 | main |
默认值 | on |
可配置选项 | on 或 off |
指令说明 | Nginx 默认是以一个主进程管理多个工作进程的工作方式,设定指令值为 off 时,Nginx 将只运行一个主进程来处理所有请求 |
配置样例如下:
master_process off;
当只由主进程处理请求时,调试进程会更加方便。
表:调试点控制指令 | |
名 称 | 调试点控制指令 |
指令 | debug_points |
作用域 | main |
默认值 | -- |
可配置选项 | stop 或 abort |
指令说明 |
该指令用于进行调试点的控制,当指令值为 stop 时,Nginx 在执行到内部调试点时就会发出 SIGSTOP 信号, 方便用户进行调试;当指令值为 abort 时则会停止进程并创建 corefile |
配置样例如下:
debug_points stop;
表:工作目录指令 | |
名称 | 工作目录指令 |
指令 | working_directory |
作用域 | main |
默认值 | -- |
指令说明 |
在 Linux 操作系统中,当进程执行出错或收到终止信号时,操作系统会将执行进程过程中,内存中的内容存储到一个文件中, 该文件被称为崩溃文件(corefile),当 Nginx 进程发生这种状况时也会生成一个崩溃文件,该崩溃文件中包含当时的堆栈 及寄存器等信息,方便用户排查问题产生的原因。该指令用于设定工作进程保存崩溃文件的目录,在 Nginx 程序崩溃时向该 目录中写入崩溃文件,Nginx 进程需要被设定有目录的写权限 |
配置样例如下:
working_directory logs
可以使用工具 objdump、GDB 进行文件分析。
表:调试文件大小指令 | |
名称 | 调试文件大小指令 |
指令 | worker_rlimit_core |
作用域 | main |
默认值 | -- |
指令说明 |
该指令是崩溃文件大小的设置指令。因为崩溃文件会存储非常详细的信息,数据量很大, 很容易把磁盘空间占满,因此需要合理限制崩溃文件的文件大小 |
配置样例如下:
worker_rlimit_core 800m;
4.事件处理
Nginx 是采用事件驱动式架构处理外部请求的,这一架构使得 Nginx 在现有硬件架构下可以处理数以万计的并发请求。通过事件处理指令的配置可以让 Nginx 与实际运行的硬件及系统进行有效的适配,从而发挥更加高效的并发处理能力。Nginx 的事件处理指令编辑在 events 指令域中,如下面表格中所示。
表:工作进程并发数指令 | |
名称 | 工作进程并发数指令 |
指令 | worker_connections |
作用域 | events |
默认值 | 512 |
指令说明 | 每个 Nginx 工作进程可处理并发连接的最大数 |
配置样例如下:
events { worker_connections 65535; }
Linux 系统下,因为每个网络连接都将打开一个文件描述符,Nginx 可处理的并发连接数受限于操作系统的最大打开文件数,同时所有工作进程的并发数也受 worker_rlimit_nofile 指令值的限制。
表:事件处理机制选择指令 | |
名 称 | 事件处理机制选择指令 |
指令 | use |
作用域 | events |
默认值 | -- |
指令说明 |
Nginx 内部有多种事件处理机制模型,以下简称事件模型。默认情况下, Nginx 会自动选择一种高效的事件模型,用户可以通过该指令自行选择事件模型进行事件处理 |
配置样例如下:
events {
use epoll;
}
Nginx 支持的事件模型有 select、poll、kqueue、epoll、/dev/poll、eventport。
表:互斥锁指令 | |
名称 | 互斥锁指令 |
指令 | accept_mutex |
作用域 | events |
默认值 | off |
可配置选项 | on 或 off |
指令说明 | 设置是否启用互斥锁模式的进程调度 |
配置样例如下:
events {
accept_mutex on;
}
在 Nginx 1.11.3 版本之前,互斥锁指令是默认开启的。
表:互斥锁等待时间指令 | |
名称 | 互斥锁等待时间指令 |
指令 | accept_mutex_delay |
作用域 | events |
默认值 | 500ms |
指令说明 |
Nginx 工作进程在互斥锁模式下需要不断地争抢互斥锁,没有互斥锁的工作进程如果争抢不到互斥锁, 会在等待时间结束后执行下一轮争抢。通过该指令可以将抢锁等待时间设置为一个较短的时间,以提高 进程争抢互斥锁的频率 |
配置样例如下:
events {
accept_mutex_delay 300ms;
}
表:多请求支持指令 | |
名称 | 多请求支持指令 |
指令 | multi_accept |
作用域 | events |
默认值 | off |
可配置选项 | on 或 off |
指令说明 | 默认情况下,每个工作进程一次只接收一个新连接。如果开启该指令,则每个工作进程将接收所有的新连接 |
配置样例如下:
events {
multi_accept on;
}
表:未完成异步操作最大数指令 | |
名称 | 未完成异步操作最大数指令 |
指令 | worker_aio_requests |
作用域 | events |
默认值 | 32 |
指令说明 | 用于设置当在 epoll 事件模型下使用 AIO 时,单个工作进程未完成异步 I/O 操作的最大数 |
配置样例如下:
events { worker_aio_requests 128; }
表:调试指定连接指令 | |
名称 | 调试指定连接指令 |
指令 | debug_connection |
作用域 | events |
默认值 | off |
可配置选项 | address 或 CIDR 或 unix: |
指令说明 | 对指定的客户端连接开启调试日志 |
配置样例如下:
events { debug_connection 127.0.0.1; debug_connection localhost; debug_connection 192.0.2.0/24; debug_connection ::1; debug_connection 2001:0db8::/32; debug_connection unix:; ... }
该指令需要 Nginx 在编译时通过--with-debug参数开启。
5.指令配置样例
本节指令的配置样例如下。
daemon on; # 以守护进程的方式运行Nginx pid logs/nginx.pid; # 主进程ID记录在logs/nginx.pid中 user nobody nobody; # 工作进程运行用户为nobody load_module "modules/ngx_http_xslt_filter_module.so"; # 加载动态模块ngx_http_xslt_ # filter_module.so error_log logs/error.log debug; # 错误日志输出级别为debug pcre_jit on; # 启用pcre_jit技术 thread_pool default threads=32 max_queue=65536; # 线程池的线程数为32,等待队列中的最大 # 任务数为65536 timer_resolution 100ms; # 定时器周期为100毫秒 worker_priority -5; # 工作进程系统优先级为-5 worker_processes auto; # 工作进程数由Nginx自动调整 worker_cpu_affinity auto; # 工作进程的CPU绑定由Nginx自动调整 worker_rlimit_nofile 65535; # 所有工作进程的最大连接数是65535 worker_shutdown_timeout 10s; # 工作进程关闭等待时间是10秒 lock_file logs/nginx.lock; # 互斥锁文件的位置是logs/nginx.lock working_directory logs # 工作进程工作目录是logs debug_points stop; # 调试点模式为stop worker_rlimit_core 800m; # 崩溃文件大小为800MB events { worker_connections 65535; # 每个工作进程的最大连接数是65535 use epoll; # 指定事件模型为epoll accept_mutex on; # 启用互斥锁模式的进程调度 accept_mutex_delay 300ms; # 互斥锁模式下进程等待时间为300毫秒 multi_accept on; # 启用支持多连接 worker_aio_requests 128; # 完成异步操作最大数为128 debug_connection 192.0.2.0/24; # 调试指定连接的IP地址和端口是192.0.2.0/24 }
3.Nginx端口监听(listen指令)
本节主要来介绍 Nginx 中与端口监听有关的配置指令,下表为端口监听指令及其相关说明。
名称 | 端口监听指令 |
指令 | listen |
作用域 | server |
默认值 | listen*:80 或 *:8000 |
指令说明 | 服务监听端口、绑定 IP、监听方式的配置 |
Nginx 服务通过 listen 指令的指令值监听网络请求,可以是 IP 协议的形式,也可以是 UNIX 域套接字。如果不设置 listen 指令,Nginx 在以超级用户运行时则监听 80 端口,以非超级用户运行时则监听 8000 端口。
listen 指令的指令值还针对监听方式提供了丰富的参数,如下表所示。
参数 | 默认值 | 参数说明 |
address | -- | 若为 IP 协议,该参数值为指定绑定监听端口的 IP 或主机名;若为 UNIX 域套接字,则该参数值为 sock 文件路径 |
port | 80 | IP 协议监听的端口 |
bind | address:port | 指定 IP 及端口 |
ipv6only | on | 只接收 IPv6 连接或接收 IPv6 和 IPv4 连接 |
default_server | -- |
当 http 指令域中包含多个虚拟主机时,该参数用于指定哪个虚拟主机是默认服务,默认将第一个顺序的 server 设为默认服务。 默认服务可以用来处理没有 server_name 匹配成功的请求 |
http2 | -- | HTTP/2 协议支持 |
spdy | -- | SDPY 协议支持,与 HTTP/2 协议不能同时存在 |
ssl | -- | SSL 支持 |
proxy_protocol | -- | 在指定监听端口上启用 proxy_protocol 协议支持 |
fastopen | number | HTTP 处于保持连接(keepalive)状态时,允许不经过三次握手的 TCP 连接的队列的最大数 |
deferred | -- | 添加该参数后,在 TCP 三次握手的过程中,检测到客户端有数据时才将 TCP 状态置为 ESTABLISHED 状态,没有数据则直接丢弃 |
reuseport | -- |
默认情况下,所有的工作进程会共享一个 socket 去监听同一 IP 和端口的组合。该参数启用后,允许每个工作进程有独立的 socket 去监听同一 IP 和端口的组合,内核会对传人的连接进行负载均衡。适用于 Linux 3.9+,DragonFly BSD 和 FreeBSD 12+ |
so_keepalive | off |
配置是否在监听的端口启用“TCP keepalive”机制。当设置为 on 时,默认等同于 so_keepalive=30m::10,表示 30 分钟无数据传 输时发送探测包,发送 10 次,发送间隔使用系统内核参数 tcp_keepalive_intvl 的设定值 |
backlog | -1/511 | 当阻塞时,设置挂起连接队列的最大长度,在 FreeBSD,DragonFly BSD 和 MacOS 操作系统上,默认值为 -1,其他平台上值为 511 |
rcvbuf | -- | socket 接收缓冲的大小,默认为 8k 字节,在接收数据比较大的场景中可以适当调整 |
sndbuf | -- | socket 发送缓冲的大小,默认为 8k 字节,在发送数据较大的场景中可以适当调整 |
setfib | number | 为监听套接字设置关联路由表,仅在 FreeBSD 系统上有效 |
accept_filter | filter | 为监听套接字设置过滤器,仅支持 FreeBSD 和 NetBSD 5.0+ 系统 |
配置样例如下:
http { server { listen 127.0.0.1:8000; # 监听127.0.0.1的8000端口 listen 127.0.0.1; # 监听127.0.0.1的默认80端口(root权限) listen 8000; # 监听本机所有IP的8000端口 listen *:8000; # 监听本机所有IP的8000端口 listen localhost:8000; # 监听locahost的8000端口 listen [::]:8000; # 监听IPv6的8000端口 listen [::1]; # 监听IPv6的回环IP的默认80端口(root权限) listen unix:/var/run/nginx.sock; # 监听域套接字文件 listen *:8000 \ # 监听本机的8000端口 default_server \ # 当前服务是http指令域的主服务 fastopen=30 \ # 开启fastopen功能并限定最大队列数为30 deferred \ # 拒绝空数据连接 reuseport \ # 工作进程共享socket这个监听端口 backlog=1024 \ # 请求阻塞时挂起队列数是1024个 so_keepalive=on; # 当socket为保持连接时,开启状态检测功能 } }
4.Nginx server_name:配置主机名称
Nginx 中的 server_name 指令主要用于配置基于名称的虚拟主机,其说明如下表所示:
名称 | 主机名指令 |
指令 | server_name |
作用域 | server |
默认值 | -- |
指令说明 | 设定所在 server 指令域的主机名 |
配置样例如下所示:
http { server { server_name example.com .example.com; # 泛域名的使用 server_name www.example.; # 多个后缀域名的使用server_name www.example.com ~^www.example.com$; # 正则表达式匹配 # 正则匹配变量的场景 server_name ~^(www\.)?(.+)$; location / { root /sites/$2; } # 正则匹配为变量的场景 server_name ~^(www\.)?(?<domain>.+)$; location / { root /sites/$domain; } } }
当 server_name 指令值中有多个主机名时,第一个主机名为首主机名。
5.Nginx处理HTTP请求
标准的 HTTP 请求从开始到结束包括请求报文和响应报文。
请求报文是客户端向服务端发起请求时告知服务端请求的方式、相关属性和请求内容的数据包,由请求行、请求头、请求体组成,这里以百度首页的请求为例,HTTP请求头结构如下图所示。
请求行是请求头内容的第一行,包括请求方法 GET,请求的 URI 地址 https://www.baidu.com,请求的协议及版本号 HTTP/1.1。
请求头还包含此次请求所设定的若干属性字段,属性字段由属性名称和属性值组成,如浏览器信息 User-Agent 等。
请求体则是请求数据,该请求是无参数的 GET 方法,请求体中无内容。
常见的请求头属性如下表所示。
属性名称 | 属性值样例 | 属性说明 |
Host | www.baidu.com | 记录用户请求的目标主机名,常用于服务端虚拟主机的区分,对应 Nginx 的 server_name 指令的配置 |
Accept | text/html, application/xhtml+xml | 描述客户端能够接收服务端返回的数据类型,Nginx 会通过 types 指令域中的内容做匹配 |
Cookie | BD_HOME=1; sugstore=1 | 客户端当前连接的所有 cookie |
Referer | https://www.baidu.com | 表示当前连接的上一个来源 URI |
Cache-Control | no-cache | 当前客户端缓存机制的控制,可通过更多的属性值参数进行缓存控制 |
Connection | keep-alive | 表示是否需要启用保持连接机制,HTTP/1.1 默认启用保持连接 |
If-None-Match | W/ "50b1c1d4f775c61:df3" | 与页面响应头中 etag 的属性值配合使用,将 etag 的内容提交给服务端,用以判断请求内容是否已经被修改,若未被修改,则返回状态码 304,客户端使用本地缓存 |
if_modified_since | -- | 当前请求 URI 页面本地缓存的最后修改时间。服务器会将实际文件的修改时间与该参数值进行比较,若一致,则返回 304,客户端读取本地缓存;若不一致,则返回服务端文件的内容 |
响应报文是服务端处理客户端请求后返回客户端的数据,数据包括响应行、响应头、响应体 3 个部分,HTTP 响应头结构如下图所示。
响应行是响应头内容的第一行,包含报文协议及版本号 HTTP/1.1、响应状态码 200、响应状态描述 OK。
响应头则包含服务端处理完请求后响应设定的若干属性字段,如 set-cookie 信息等。
响应体为返回的处理结果,本次请求的响应体是 HTML 页面数据。
HTTP 响应状态码是响应报文中对 HTTP 请求处理结果的重要标识,响应状态码是由 RFC 2616 规范定义的,并由互联网号码分配局(Internet Assigned Numbers Authority)维护,状态码可以分为以下 5 个类别。
-
- 1××(消息):表示服务端已经接收到请求,正在进行处理;
- 2××(处理成功):表示服务端已经正确处理完客户端的 HTTP 请求;
- 3××(重定向):服务端接收到 HTTP 请求,并将其 HTTP 请求重定向到客户本地或其他服务器进行处理;
- 4××(客户端请求有误):客户端提交的请求不符合规范或未被授权、禁止访问等;
- 5××(服务端处理出错):服务端无法正常完成请求操作,如超时等。
常见的响应头属性如下表所示。
属性名称 | 属性值样例 | 属性说明 |
Content-Type | text/html; charset=utf-8 | 告知客户端返回数据的类型 |
Connection | keep-alive | 告知客户端是否启用保持连接机制 |
Cache-Control | no-cache | 告知客户端对缓存机制的控制 |
ETag | "50b1c 1d4f775c61:df3" | 当前响应数据的实体标签值,用于在客户端与服务端提交相同请求时判断请求内容是否有修改 |
Location | https://map.baidu.com/ | 告知客户端跳转到指定的 URI |
Set-Cookie | username=john.wang | 通知客户端修改本地 cookie 内容 |
当 Nginx 接收 HTTP 请求后,处理相关的配置指令如下表所示。
指令 | 作用域 | 默认值 | 指令值选项 | 指令说明 |
ignore_invalid_headers | http, server | on | on 或 off |
忽略请求头中的无效属性字段,请求头属性字段中,属性名称默认由英文字符、数字和连接符组成,不符合此标准的 属性名均为无效属性名。当指令值为on时,不对无效的属性名称进行过滤 |
underscores_in_headers | http, server | off | on 或 off |
请求头中属性名称的定义中“_”是无效连接符,启用该指令后,“_”将被认为是有效的连接符。如果该指令值为 off, 则按照 ignore_invalid_headers 指令的配置进行处理 |
client_header_buffer_size | http, server | 1k | -- |
设置存放读取客户端请求头的缓冲区的大小,默认值为1K,当请求头的数据因cookie过长等其他原因超过所设定的大小 时,会按照large-client header buffers的指令配置进行处理 |
large_client_header_buffers | http, server | 48k | -- |
当客户请求头的大小超过 client_header_buffer_size 指令设置的值时,会将超出的部分转移到该缓冲区中。在默认 配置下,超大请求头第一次可分配到一个 8KB 的缓冲区块,请求行的大小不能超过该缓冲区块的大小,否则将返回 414 错误。超出 8KB 的请求头会被循环转移到新的缓冲区块中,最多转移 4 次,当超过该值时,则会返回 400 错误 |
client_header_timeout | http, server | 60s | -- | 读取客户端请求头的最大超时时间 |
request_pool_size | http, server | 4k | -- |
Nginx 开始处理请求时,会为每个请求分配一个 4KB 大小的内存池,以减少内核对小块内存的分配次数,HTTP 请求结 束后会回收为其分配的内存池 |
client_max_body_size | http, server, Location | 1m | -- | HTTP 请求时,请求体的最大值。当请求头中属性 Content-Length 的大小超过指令配置时,返回状态码 408 |
client_body_buffer_size | http, server, Location | -- | -- |
设置读取客户请求体的缓冲区大小,当请求体的大小超过该设定值后,会按照 client_body_in_single_buffer 指令的配 置选择部分或全部写入 client_body_temp_path 指令设定的文件中。默认配置下,32 位系统下缓冲区的大小是 8KB,64 位系统下缓冲区的大小是 16KB |
client_body_in_file_only | http, server, Location | off | off 或 clean 或 on |
默认情况下是优先使用缓存,在请求体超出请求体缓冲区的大小时再写入文件。启用该指令后将禁用缓冲区,请求体会被直接 写入 client_body_temp_path 指令设定的文件中 |
client_body_temp_path | http, server, Location | client_body_temp_path_client_body_temp | -- | 请求体被写入文件的临时目录 |
client_body_timeout | http, server, Location | 60s | -- |
当 HTTP 请求建立连接后,客户端在超过设定时间后仍未发送请求体内容到服务端,则 Nginx 认为请求体超时,将返回响应 状态码 408 |
if_modified_since | http, server, Location | exact | off 或 exact 或 before | 在请求头中存在属性if modified since时,关闭或设置客户端缓存文件修改时间的服务端校验功能 |
etag | http, server, Location | on | on 或 off |
etag(Entity Tag),用于在响应头中返回文件实体标签,与同一文件的下一次请求头中 If-None-Match 属性值组合检查 文件是否被修改,未修改则返回响应状态码 304,否则返回最新的文件内容 |
max_ranges | http, server, Location | -- | -- |
默认为不限制大小,当客户端以 byte-range 方式获取数据请求时,该指令限定了允许的最大值。当指令值为 0 时,则关 闭以 byte-range 方式获取数据的功能 |
types | http, server, Location | -- | -- | 被请求文件扩展名与 MIME 类型映射表 |
types_hash_max_size | http, server, Location | 1024 | -- | 设定 MIME 类型哈希表的大小 |
types_hash_bucket_size | http, server, Location | -- | -- | 设定 MIME 类型哈希桶的大小,默认值与 CPU 缓存行的大小一致,有 32、64、128(单位:字节)3 个值 |
error_page | http, server, Location | -- | -- | 当 HTTP 请求发生错误时,可以根据响应状态码定义一个返回的页面或执行跳转 |
recursive_error_pages | http, server, Location | off | off 或 on | 当使用 error_pages 设定多层内部访问时,仍可处理上一层级返回的响应状态码 |
server_tokens | http, server, Location | on | on 或 off | 默认在错误信息响应头中增加属性字段“Server”以标识 Nginx 的版本号 |
msie_padding | http, server, Location | on | on 或 off | 在响应状态大于或等于 400 时,会在响应报文中添加注释,使响应报文大小达到 512 字节。仅适用于 msie 客户端 |
配置样例如下:
http { ignore_invalid_headers off; underscores_in_headers on; client_header_buffer_size 2k; large_client_header_buffers 10 8k; client_header_timeout 180s; request_pool_size 4k; client_max_body_size 100m; client_body_in_file_only on; client_body_temp_path /tmp/nginx/client_temp 1 2; client_body_timeout 120s; if_modified_since before; etag off; max_ranges 1024 ; types_hash_max_size 2048; types_hash_bucket_size 64; error_page 404 /404.html; error_page 500 502 503 504 /50x.html; error_page 404 = @fallback; location @fallback { proxy_pass http://backend; } error_page 404 =200 /empty.gif; location /download/ { types { application/octet-stream yaml; } default_type application/octet-stream; } proxy_intercept_errors on; # 当上游服务器返回非200状态码时,返回代理服务器处理 recursive_error_pages on; # 启用多级错误跳转功能 location / { error_page 404 = @fallback; # 当前URL请求为404时执行内部请求@fallback } location @fallback { proxy_pass http://backend; # 当前所有请求代理到上游服务器backend error_page 502 = @upfallback; # 当上游服务器返回502状态码时,执行内部请求@upfallback } location @upfallback { proxy_pass http://newbackend; # 当前的所有请求代理到上游服务器newbackend } server_tokens off; msie_padding off; }
6.Nginx localhost路由匹配规则
URI 即统一标识资源符,通用的 URI 语法格式如下:
scheme:[//[user[:password]@]host[:port]][/path][?query][#fragment]
格式说明如下:
-
- 在 Nginx 的应用场景中,URL 与 URI 并无明确区别。URI 标准(RFC3986)中约定,URL 是 URI 的一个子集;
- scheme 是 URI 请求时遵守的协议,常见的有 HTTP、HTTPS、FTP;
- host[:port] 是主机名与端口号,HTTP 协议的默认端口是 80,HTTPS 协议的默认端口是 443;
- [/path] 是访问路径与访问文件名;
- [?query] 是访问参数,访问参数以“?”开始作标识,由多个以“&”连接的 key=value 形式的字符串组成。
1.URI 匹配规则
location 是 Nginx 对 HTTP 请求中的 URI 进行匹配处理的指令,location 的语法形式如下:
location [=|~|~*|^~|@] pattern { ... }
其中,[=|~*|^~|@]
部分称为 location 修饰语(Modifier),修饰语定义了与 URI 的匹配方式。pattern 为匹配项,可以是字符串或正则表达式。
无修饰语:完全匹配 URI 中除访问参数以外的内容,匹配项的内容只能是字符串,不能是正则表达式。
location /images { root /data/web; }
修饰语“=”:完全匹配 URI 中除访问参数以外的内容,Linux 系统下会区分大小写,Windows 系统下则不会。
location = /images { root /data/web; }
修饰语“~”:完全匹配 URI 中除访问参数以外的内容,Linux 系统下会区分大小写,Windows 系统下则会无效。匹配项的内容必须是正则表达式。
location ~ /images/.*\.(gif|jpg|png)$ { root /data/web; }
修饰语“~*”:完全匹配 URI 中除访问参数以外的内容,不区分大小写。匹配项的内容必须是正则表达式。
location ~* \.(gif|jpg|png)$ { root /data/web; }
修饰语“^~”:完全匹配 URI 中除访问参数以外的内容,匹配项的内容如果不是正则表达式,则不再进行正则表达式测试。
location ^~ /images { root /data/web; }
修饰语“@”:定义一个只能内部访问的 location 区域,可以被其他内部跳转指令使用,如 try_files 或 error_page。
location @images { proxy_pass http://images; }
2.匹配顺序
1) 先检测匹配项的内容为非正则表达式修饰语的 location,然后再检测匹配项的内容为正则表达式修饰语的 location。
2) 匹配项的内容为正则与非正则都匹配的 location,按照匹配项的内容为正则匹配的 location 执行。
3) 所有匹配项的内容均为非正则表达式的 location,按照匹配项的内容完全匹配的内容长短进行匹配,即匹配内容多的 location 被执行。
4) 所有匹配项的内容均为正则表达式的 location,按照书写的先后顺序进行匹配,匹配后就执行,不再做后续检测。
3.其他事项
当 location 为正则匹配且内部有 proxy_pass 指令时,proxy_pass 的指令值中不能包含无变量的字符串。修饰语“^~”不受该规则限制。
location ~ /images { proxy_pass http://127.0.0.1:8080; # 正确的指令值 proxy_pass http://127.0.0.1:8080$request_uri; # 正确的指令值 proxy_pass http://127.0.0.1:8080/image$request_uri; # 正确的指令值 proxy_pass http://127.0.0.1:8080/; # 错误的指令值 }
4.访问路由指令
访问路由指令如下面表格所示。
表:合并空斜线指令 | |
名称 | 合并空斜线指令 |
指令 | merge_slashes |
作用域 | http, server, location |
默认值 | on |
指令值选项 | off 或 on |
指令说明 | 当指令值为 on,在访问路径中相邻斜线内容为空时进行合并 |
配置样例如下:
http {
merge_slashes off;
}
表:跳转主机名指令 | |
名称 | 跳转主机名指令 |
指令 | server_name_in_redirect |
作用域 | http, server, location |
默认值 | off |
指令说明 |
默认情况下,Nginx 重定向时,会用当前 server 指令域中主机的 IP 与 path 拼接成完整的 URL 进行重定向。 开启该参数后,Nginx 会先查看当前指令域中 server_name 的第一个主机名,如果没有,则会查找请求头中 host 字段的内容,如果再没有则会用 IP 与 path 进行拼接 |
配置样例如下:
http {
server_name_in_redirect on;
}
表:跳转端口指令 | |
名称 | 跳转端口指令 |
指令 | port_in_redirect |
作用域 | http, server, location |
默认值 | on |
指令说明 | Nginx 重定向时,会用当前 server 指令域的监听端口与主机拼接成完整的URL进行重定向。当指令值为 off 时,则默认用 80 端口 |
配置样例如下:
http {
port_in_redirect on;
}
表:子请求输出缓冲区大小指令 | |
名称 | 子请求输出缓冲区大小指令 |
指令 | subrequest_output_buffer_size |
作用域 | http, server, location |
默认值 | 4k 或 8k |
指令说明 | 设置用于存储子请求响应报文的缓冲区大小,默认值与操作系统的内存页大小一致 |
配置样例如下:
http {
subrequest_output_buffer_size 64K;
}
表:绝对跳转指令 | |
名称 | 绝对跳转指令 |
指令 | absolute_redirect |
作用域 | http, server, location |
默认值 | on |
指令值选项 | off 或 on |
指令说明 |
Nginx 发起的重定向使用绝对路径做跳转,即用主机名和端口及访问路径的方式, 如果关闭的话,则跳转为默认相对当前请求的主机名和端口的访问路径 |
配置样例如下:
http {
absolute_redirect off;
}
表:响应刷新指令 | |
名称 | 响应刷新指令 |
指令 | msie_refresh |
作用域 | http, server, location |
默认值 | on |
指令值选项 | on 或 off |
指令说明 |
Nginx 处理页面跳转或刷新的方式通常是以向客户端返回 3xx 状态码来实现。该指令是当客户端为 msie 时, 在返回 HTML 头部添加“<meta http-equiv=\"Refresh\" content=\"0;\" url=*>” |
配置样例如下:
http {
msie_refresh off;
}
7.Nginx rewrite重定向配置详解
访问重写 rewrite 是 Nginx HTTP 请求处理过程中的一个重要功能,它是以模块的形式存在于代码中的,其功能是对用户请求的 URI 进行 PCRE 正则重写,然后返回 30× 重定向跳转或按条件执行相关配置。
rewrite 模块内置了类似脚本语言的 set、if、break、return 配置指令,通过这些指令,用户可以在 HTTP 请求处理过程中对 URI 进行更灵活的操作控制。rewrite 模块提供的指令可以分两类,一类是标准配置指令,这部分指令只是对指定的操作进行相应的操作控制;另一类是脚本指令,这部分指令可以在 HTTP 指令域内以类似脚本编程的形式进行编写。
1.标准配置指令
常用的标准配置指令如下面表格所示。
表:rewrite 日志记录指令 | |
名称 | rewrite 日志记录指令 |
指令 | rewrite_log |
作用域 | http, server, location |
默认值 | off |
指令值选项 | on 或 off |
指令说明 | 当指令值为 on 时,rewrite 的执行结果会以 notice 级别记录到 Nginx 的 error 日志文件中 |
配置样例如下:
http {
rewrite_log off;
}
表:未初始化变量告警日志记录指令 | |
名称 | 未初始化变量告警日志记录指令 |
指令 | uninitialized_variable_warn |
作用域 | http, server, location |
默认值 | on |
指令值选项 | on 或 off |
指令说明 | 指令值为 on 时,会将未初始化的变量告警记录到日志中 |
配置样例如下:
http {
uninitialized_variable_warn off;
}
表:rewrite 指令 | |
名称 | rewrite 指令 |
指令 | rewrite |
作用域 | server, location |
默认值 | on |
指令值选项 | on 或 off |
指令说明 | 对用户的 URI 用正则表达式的方式进行重写,并跳转到新的 URI |
配置样例如下:
http { rewrite ^/users/(.*)$ /show?user=$1 last; }
rewrite 访问重写是通过 rewrite 指令实现的,rewrite 指令的语法格式如下:
rewrite regex replacement [flag];
1) regex 是 PCRE 语法格式的正则表达式。
2) replacement 是重写 URI 的改写规则。当改写规则以“http://”“https://”或“$scheme”开头时,Nginx 重写该语句后将停止执行后续任务,并将改写后的 URI 跳转返回客户端。
3) flag 是执行该条重写指令后的操作控制符。操作控制符有如下 4 种:
-
- last:执行完当前重写规则跳转到新的 URI 后继续执行后续操作;
- break:执行完当前重写规则跳转到新的 URI 后不再执行后续操作。不影响用户浏览器 URI 显示;
- redirect:返回响应状态码 302 的临时重定向,返回内容是重定向 URI 的内容,但浏览器网址仍为请求时的 URI;
- permanent:返回响应状态码 301 的永久重定向,返回内容是重定向 URI 的内容,浏览器网址变为重定向的 URI。
2.脚本指令
常见的脚本指令如下面表格所示。
表:设置变量指令 | |
名称 | 设置变量指令 |
指令 | set |
作用域 | server, location, if |
指令说明 | set 指令,可以用来定义变量 |
配置样例如下:
http { server{ set $test "check"; } } http{ server { listen 8080; location /foo { set $a hello; rewrite ^ /bar; } location /bar { # 如果这个请求来自“/foo”,$a的值是“hello”。如果直接访问“/bar”,$a的值为空 echo “a = [$a]”; } } }
用 set 指令创建变量后,变量名是 Nginx 配置全局域可用的,但变量值只在有该变量赋值操作的 HTTP 处理流程中可用。
http{ server { listen 8080; location /foo { set $a hello; rewrite ^ /bar; } location /bar { # 如果这个请求来自“/foo”,$a的值是“hello”。如果直接访问“/bar”,$a的值为空 if ( $a = “hello” ){ rewrite ^ /newbar; } } } }
当 set 指令后只有变量名时,系统会自动创建该变量,变量值为空。
http {
server{
set $test;
}
}
变量插值如下:
http { server{ set $test "check "; if ( "${test}nginx" = "nginx" ){ #${test}nginx的值为"check nginx" } } }
表:条件判断指令 | |
名称 | 条件判断指令 |
指令 | if |
作用域 | server, location |
指令说明 | 条件判断指令 |
配置样例如下:
http { server { if ($http_cookie ~* "id=([^;]+)(?:;|$)") { set $id $1; } } }
1) 当判断条件为一个变量时,变量值为空或以 0 开头的字符串都被判断为 false。
2) 变量内容字符串比较操作运算符为“=”或“!=”。
3) 进行正则表达式比较时,有以下 4 个操作运算符:
-
- “~”:区分大小写匹配;
- “~*”:不区分大小写匹配;
- “!~”:区分大小写不匹配;
- “!~*”:不区分大小写不匹配。
4) 进行文件或目录比较时,有以下 4 个操作运算符:
-
- “-f”:判断文件是否存在,可在运算符前加“!”表示反向判断。
- “-d”:判断目录是否存在,可在运算符前加“!”表示反向判断。
- “-e”:判断文件、目录或链接符号是否存在,可在运算符前加“!”表示反向判断。
- “-x”:判断文件是否为可执行文件,可在运算符前加“!”表示反向判断。
表:终止指令 | |
名称 | 终止指令 |
指令 | break |
作用域 | server, location, if |
指令说明 | 终止后续指令的执行 |
配置样例如下:
http { server { if ($slow) { limit_rate 10k; break; } } }
表:跳转指令 | |
名称 | 跳转指令 |
指令 | return |
作用域 | server, location, if |
指令说明 | 向客户端返回响应状态码或执行跳转 |
配置样例如下:
http { server { if ($request_method = POST) { return 405; } } }
1) return 的指令值有以下 4 种方式。
-
- return code:向客户端返回指定 code 的状态码,当返回非标准的状态码 444 时,Nginx 直接关闭连接,不发送响应头信息。
- return code text:向客户端发送带有指定 code 状态码和 text 内容的响应信息。因要在客户端显示 text 内容,所以 code 不能是 30×。
- return code URL:这里的 URL 可以是内部跳转或变量 $uri,也可以是有完整 scheme 标识的 URL,将直接返回给客户端执行跳转,code 只能是 30×。
- return URL:此时默认 code 为 302,URL 必须是有完整 scheme 标识的 URL。
2) return 也可以用来调试输出 Nginx 的变量。
8.Nginx访问控制简述
HTTP 核心配置指令中提供了基本的禁止访问、传输限速、内部访问控制等功能配置。配置指令如下表所示。
表:请求方法排除限制指令 | |
名称 | 请求方法排除限制指令 |
指令 | limit_except |
作用域 | http, server, location |
默认值 | -- |
指令说明 | 对指定方法以外的所有请求方法进行限定 |
配置样例如下:
http{ limit_except GET { allow 192.168.1.0/24; # 允许192.168.1.0/24范围的IP使用非GET的方法 deny all; # 禁止其他所有来源IP的非GET请求 } }
表:组合授权控制指令 | |
名称 | 组合授权控制指令 |
指令 | satisfy |
作用域 | http, server, location |
默认值 | all |
指令值选项 | all 或 any |
指令说明 |
默认情况下,在响应客户端请求时,当 ngx_http_access_module、ngx_http_auth_basic_module、 ngx_http_auth_request_module、ngx_http_auth_jwt_module 模块被限定的访问控制条件都符合时, 才允许授权访问。当指令值为 any 时,ngx_http_access_module、ngx_http_auth_basic_module、 ngx_http_auth_request_module、ngx_http_auth_jwt_module 模块的访问控制条件,符合任意一个, 则认为可以授权访问 |
配置样例如下:
location / { satisfy any; allow 192.168.1.0/32; deny all; auth_basic "closed site"; auth_basic_user_file conf/htpasswd; }
表:内部访问指令 | |
名称 | 内部访问指令 |
指令 | internal |
作用域 | http, server, location |
默认值 | -- |
指令说明 | 限定 location 的访问路径来源为内部访问请求,否则返回响应状态码 404 |
1) Nginx 限定以下几种类型为内部访问。
-
- 由 error_page 指令、index 指令、random_index 指令和 try_files 指令发起的重定向请求;
- 响应头中由属性 X-Accel-Redirect 发起的重定向请求,等同于 X-sendfile,常用于下载文件控制的场景中;
- ngx_http_ssi_module 模块的 include virtual 指令、ngx_http_addition_module 模块、auth_request 和 mirror 指令的子请求;
- 用 rewrite 指令对 URL 进行重写的请求。
2) 内部请求的最大访问次数是 10 次,以防错误配置引发内部循环请求,超过限定次数将返回响应状态码 500。
配置样例如下:
error_page 404 /404.html; location = /404.html { internal; }
表:响应限速指令 | |
名称 | 响应限速指令 |
指令 | limit_rate |
作用域 | http, server, location |
默认值 | 0 |
指令说明 | 服务端响应请求后,被限定传输速率的大小。速率是以字节/秒为单位指定的,0 值表示禁用速率限制 |
配置样例如下:
server { location /flv/ { flv; limit_rate_after 500k; # 当传输速率到500KB/s时执行限速 limit_rate 50k; # 限速速率为50KB/s } }
响应速率也可以在 proxy_pass 的响应头属性 X-Accel-Limit-Rate 字段中设定;可以通过proxy_ignore_headers、fastcgi_ignore_headers、uwsgi_ignore_headers和 scgi_ignore_headers 指令禁用此项功能;在 Nginx 1.17.0 以后的版本中,参数值可以是变量。
map $slow $rate { 1 4k; 2 8k; } limit_rate $rate;
表:响应最大值后限速指令 | |
名称 | 响应最大值后限速指令 |
指令 | limit_rate_after |
作用域 | http, server, location |
默认值 | 0 |
指令说明 | 服务端响应请求后,当向客户端的传输速率达到指定值时,按照响应限速指令进行限速 |
配置样例如下:
location /flv/ {
flv;
limit_rate_after 500k;
limit_rate 50k;
}
9.Nginx root指令:根目录配置
用户请求的最终结果是要返回数据,当响应文件在 Nginx 服务器本地时,需要进行本地文件位置、读或写、返回执行结果的操作。Nginx 中的 root 指令可以设定请求 URL 的本地文件根目录,如下表所示。
名称 | 根目录指令 |
指令 | root |
作用域 | http, server, location |
默认值 | on |
指令说明 | 设定请求 URL 的本地文件根目录 |
配置样例如下:
location /flv/ { root /data/web; }
当 root 指令在 location 指令域时,root 设置的是 location 匹配访问路径的上一层目录,样例中被请求文件的实际本地路径为 /data/web/flv/。
location 中的路径是否带“/”,对本地路径的访问无任何影响。
10.Nginx alias指令:虚拟目录配置
Nginx 中想要配置虚拟目录可以使用 alias 指令,该指令的介绍如下表所示:
名 称 | 访问路径别名指令 |
指令 | alias |
作用域 | location |
默认值 | -- |
指令说明 |
默认情况下,本地文件的路径是 root 指令设定根目录的相对路径, 通过 alias 指令可以将匹配的访问路径重新指定为新定义的文件路径。 |
配置样例如下:
server{ listen 8080; server_name www.nginxtest.org; root /opt/nginx-web/www; location /flv/ { alias /opt/nginx-web/flv/; } location /js { alias /opt/nginx-web/js; } location /img { alias /opt/nginx-web/img/; } }
可以用如下命令进行访问测试:
curl http://127.0.0.1:8080/flv/ curl -L http://127.0.0.1:8080/js curl http://127.0.0.1:8080/js/ curl -L http://127.0.0.1:8080/img curl http://127.0.0.1:8080/img/
alias 指定的目录是 location 路径的实际目录,其所在 location 的 rewrite 指令不能使用 break 参数。
11.Nginx配置项try_files简介
try_files 指令是在 Nginx0.7.27 版本中开始加入的,它可以按顺序检查文件是否存在,并返回第一个找到的文件,如果未找到任何文件,则会调用最后一个参数进行内部重定向,如下表所示:
名称 | 文件判断指令 |
指令 | try_files |
作用域 | server、location |
默认值 | -- |
指令说明 | 用于顺序检查指定文件是否存在,如果不存在,则按照最后一个指定 URI 做内部跳转 |
配置样例如下:
location /images/ { # $uri存在则执行代理的上游服务器操作,否则跳转到default.gif的location try_files $uri /images/default.gif; } location = /images/default.gif { expires 30s; }
跳转的目标也可以是一个location区域,脚本如下:
http{ location / { try_files /system/maintenance.html $uri $uri/index.html $uri.html @mongrel; } location @mongrel { proxy_pass http://mongrel; } }
12.Nginx配置项sendfile:零拷贝
Nginx 中的 sendfile 配置项用来在两个文件描述符之间直接传递数据(完全在内核中操作),从而避免了数据在内核缓冲区和用户缓冲区之间的拷贝,操作效率很高,被称之为零拷贝,如下表所示:
名称 | 零复制指令 |
指令 | sendfile |
作用域 | http、server、location |
默认值 | off |
指令值选项 | on 或 off |
指令说明 | 启用零复制(sendfile)。零复制(也称零拷贝)是读取本地文件后向网络接口发送文件内容的文件传输机制 |
配置样例如下:
http {
sendfile on;
}
默认配置下,Nginx 读取本地文件后,在进行网络传输时会先将硬盘文件从硬盘中读取到 Nginx 的文件缓冲区中,操作流程为硬盘 → 内核文件缓冲区 → 应用缓冲区。然后将 Nginx 文件缓冲区的数据写入网络接口,操作流程:应用缓冲区 → 内核网络缓冲区 → 网络接口。
Nginx 的本地文件在进行网络传输的过程中,经历了上述两个操作过程,两次操作都在内核缓冲区中存储了相同的数据。为了提高文件的传输效率,内核提供了零复制技术,该技术支持文件在内核缓冲区内直接交换打开的文件句柄,无须重复复制文件内容到缓冲区,则上述两个操作的流程变为:硬盘 → 内核文件缓冲区 → 内核网络缓冲区 → 网络接口。
零复制技术减少了文件的读写次数,提升了本地文件的网络传输速度。内核缓冲区的默认大小为 4096B。
13.Nginx日志记录配置:log_not_found、log_subrequest
Nginx 中的日志记录指令如下面表格所示。
表:不存在文件日志指令 | |
名称 | 不存在文件日志指令 |
指令 | log_not_found |
作用域 | http、server、location |
默认值 | on |
指令值选项 | on 或 off |
指令说明 | 用于设定如果文件不存在错误是否写入日志 |
配置样例如下:
http {
log_not_found on;
}
表:子请求访问日志指令 | |
名称 | 子请求访问日志指令 |
指令 | log_subrequest |
作用域 | http、server、location |
默认值 | on |
指令值选项 | on 或 off |
指令说明 | 用于设定子请求的访问记录是否写入日志 |
配置样例如下:
http {
log_subrequest on;
}