关于 Nginx 系列其他文章的传送门
-
《 老司机都在用的 Nginx 实用配置 》 您当前所在位置

一、前言¶
2019 年 3 月,Nginx 的市场占有率开始反超 Apache,到今天已经逐步拉开距离,一直霸占着榜首。

数据来源参考https://news.netcraft.com/
或许你已经在使用 Nginx 承载你的网站文件,又或许用 Nginx 当做代理服务器,这里分享一些实用的 Nginx 配置,帮助你成为熟练驾驶 Nginx 的“老司机”,下面先了解几个重要的知识点(敲黑板)
二、概念¶
Web 程序的工作模型¶
Linux 中的程序是都是以 进程 和 子进程 的方式来运行,像 Nginx、Apache 等,大体上有以下几种 Web 工作模型:
- 进程模型:一个子进程只处理一个请求, 比如 Prefork。
- 机制:使用
select()poll(),限制在最大 1024 个进程,可以调大,但是进程多了 CPU 切换频繁,不建议。
- 机制:使用
- 线程模型:一个子进程生成多个线程,每个线程处理一个请求,例如 Worker。
- 事件驱动模型:一个进程同时处理多个请求。
由于在 linux 中进程是轻量化设计(LWP)的,进程和线程对资源的开销是差不多的。所以 Apache 中无论是 Prefork 还是 Worker,在 Linux 中没有显著区别,无非是运行方式不一样。但是 event 模型,已经开始采用事件驱动的模型,一个进程可以同时处理多个请求,效率极高。
而 Nginx 一开始就是依据 非阻塞 IO 的模型设计并制造的,并且支持 异步 IO。

IO 模型¶
说 IO 模型 前先了解两个概念:
阻塞/非阻塞¶
主要关注调用者在等待结果返回之前的状态。(图上半部分)
- 阻塞 blocking
- 指进程提交 IO 请求后,需要等待数据从磁盘复制到内核内存中,在复制完成之前,进行被挂起,进入睡眠状态。
- 例如:在饭店点了一碗面,厨师没做完之前你必须在柜台前等待。
- 非阻塞 nobloking
- 指进程提交 IO 请求后,无需原地等待数据复制的过程,可以先去做别的事,进程不会被挂起。
- 例如:在饭店点了一碗面,然后找了个座位坐着,边玩手机边等。
同步/异步¶
关注是消息通信机制。(图下半部分)
- 同步 asynchronous
- 进程需要将数据从内核内存中复制到用户内存中,期间不能做别的事,等复制完才能继续执行其他操作。
- 例如:面做好后,需要自己去柜台把面端回到座位。
- 异步 asynchronous
- 进程提交 IO 请求后就去忙别的事了,内核把数据的所有复制过程都完成后,通过状态、通知或者回调机制,主动通知进程。
- 例如:面做好后,有服务员帮你把面端过来。
五种 IO 模型¶

-
同步阻塞型(闲等待)
-
同步非阻塞(忙等待)
-
IO 复用
进程找一个代理 select,而不直接与内核打交道,系统调用交于 select 进行处理。
select 可以同时接收多个进程的请求。但是用户进程依旧阻塞于 select 。
数据到达内核内存后,进程将内核内存中的数据复制到用户内存。 -
事件驱动
进程提交 IO 请求后,去处理其他任务,等数据从磁盘复制到内核空间后,通过 SIGIO 告知进程,这个过程是不阻塞的。但是进程还是需要自己把数据复制到用户内存中。 -
异步 IO
用户进程不受阻塞,所有的请求,数据拷贝过程都由内核完成,进程可以接收更多的用户请求。
IO 调用方式¶
复用型 IO 调用:
select():最大 1024poll():
事件驱动 IO 调用:
- epoll(Linux):libevent
- Kqueue(BSD):
- /dev/poll(Solaris)
三、Nginx 介绍¶
介绍¶
虽然 Apache 支持的模块众多,但是 Nginx 的出生就是为了解决 C10K 的问题而设计的,不仅支持 事件驱动 IO,还支持 异步 IO。

特性:异步、事件驱动和非阻塞。
- 并发请求处理:通过
epoll/select。 - 文件 IO:高级 IO sendfile,异步,mmap。
Nginx 功能示意图¶

程序模型为:Master/Worker
- Master 负责:
- 加载配置文件
- 启动 workers
- 进行非中断升级
- Worker 负责:
- 处理并响应用户请求
模块化¶
Nginx 是高度模块化,但是早期不支持模块的动态装卸载,1.10 后的版本支持部分模块的动态装卸载。
模块分类:
- 核心模块:
core module - 标准模块:
- 静态网站模块:
HTTP modulesStandard HTTP modulesOptional HTTP modules
- 邮件服务器模块:
Mail modules - 传输层代理:
Stream modules
- 静态网站模块:
- 第三方模块:
3rd party modules 进程
主要功能¶
以下功能一般不混用
- Web Server:静态的 Web 资源服务器。
- Proxy Server:各种反向代理。
- http
- smtp
- pop3/imap4
- Stream Server:4 层代理模块,tcp/udp 协议的请求转发。
四、安装及配置¶
安装¶
官网这里可以查看最新版本,版本的第 2 位为偶数的是 Stable。
安装方法有三种:
- 官网下载源码编译安装。
- epel 仓库,为追求稳定,版本较老,建议生产使用。
- 官方仓库。
这里是测试环境,所以使用官方仓库最新版,从官网复制 repo 到本地,然后直接 yum install nginx -y 就好了。
配置文件¶
Nginx 的配置文件按类型分组:
main block:主配置段,全局配置段,对所有配置段均生效。event {}:事件驱动相关配置。http {}:Web 相关server {}:虚拟主机、反向代理
mail {}:邮件相关stream {}:流式的 4 层调度机制
注意:
-
指令遵循 C 的语法,必须以分号结尾。
-
支持使用配置变量。
- 内建变量:由 Nginx 模块引入,可直接引用。
- 自定义变量:由用户使用
set命令定义。- 设置变量:
set variable_name value; - 引用变量:
$variable_name
- 设置变量:
1. main 段配置¶
正常运行必备类¶
User¶
- 设置运行主控进程 master 的用户身份。
user user [group];
PID¶
- 指定 Nginx 守护进程的 PID 文件路径。
pid /PATH/TO/PID_FILE;
include¶
- 指明包含进来的其他配置文件。
include file | *.conf;
load_modelu¶
- 指定加载的动态模块。
load_modelu file;
性能优化相关类¶
worker_processes¶
- worker 进程的数量,通常应该小于等于当前主机 CPU 物理核心数。
worker_processes NUMBER | auto;:设置为auto的话为当前物理 CPU 核心数。
worker_cpu_affinity¶
- 设置 Nginx 进程的 CPU 亲缘性。
woker_cpu_affinity MASK;auto:自动绑定00000001:0 号 CPU00000010:1 号 CPU00000100:2 号 CPU00000011:0 号和 1 号 CPU
worker_priority¶
- 设置 worker 的进程优先级。
worker_priority [ -20,20 ];
worker_rlimit_nofile¶
- workder 进程能够打开的文件数量上限。
worker_rlimit_nofile NUMBER;
调试及定位问题类¶
daemon¶
- 是否以守护进程方式运行 Nignx。
daemon on | off;
master_process¶
- 是否以 master/worker 模型运行 nginx,默认为
on,设置off的话则只让 master 处理请求。 master_process:on | off;
error_log¶
- 设置日志文件及记录级别。
error_log file [level];
事件驱动相关类¶
属于 events 配置段:
1 | events { |
worker_connections¶
- 单个 worker 进程所能打开的最大并发连接数量。
worker_connections NUMBER;- 所以整个 Nginx 的最大并发连接上限等于
worker_processes * worker_connections;
use¶
- 指明处理并发连接请求的模型。
use epoll | select:epoll:事件驱动;select:IO 复用。
accept_mutes¶
- 为避免“惊群效应”,设置是否开启互斥锁。
accept_mutes on:意味着由各 worker 轮流处理新请求。accept_mutes Off:意味着每个新请求的到达都会通知所有的 worker 进程。
2. http 段配置¶
http 中定义的配置对所有 server 生效。
而 server 的配置仅 server 范围生效。
示例:
1 | http { |
3. server 段配置¶
一个 server {} 段代表一个虚拟主机。
1 | server{ |
listen address¶
- 设置监听选项。
listen address[:port] | PORT [default_server] [ssl];default_server:设置当没有匹配到域名时,默认从上而下选第一个,也可以手动设置默认虚拟主机。ssl:强制仅能使用 ssl 连接。
server_name¶
- 指明虚拟主机的主机名称,后可跟多个由空白字符分隔的字符串。
server_name NAME...;- 支持
*通配任意长度的任意字符。server_name *.baidu.com www.monster.* - 支持
~起始的字符做正则表达式模式匹配。server_name ~^www\d+\.baidu\.com$ - 匹配顺序:
(1). 首先是字符串精确匹配。
(2). 左侧*通配符。
(3). 右侧*通配符。
(4). 正则表达式,不建议使用,对性能有影响。
- 支持
root¶
- 设置 Web 资源路径映射,用于指明用户请求的 url 所对应的本地文件系统上的文档所在目录路径,类似 Apache 中的
Document Root。 root path;- 可用配置段:
http,server,location - 注意:
location中使用root指令和alias指令的意义不同:root:给定的 路径 对应于 location 中的/uri/左侧的/alias:给定的 路径 对应于 location 中的/uri/右侧的/
alias¶
- 定义本地文件路径的别名,
root的另一种机制。仅能用于location上下文! alias PATH;
location¶
- 根据请求的 url 设置配置。
location [ = | ~ | ~* | ^~ ] uri { ... };- 一个
server中location配置段可存在多个,用于实现从 uri 到文件系统的路径映射。=:对 URI 做精确匹配,100% 吻合。^~:对 URI 最后一个/的左半部分做匹配检查,不区分字符大小写。~:对 URI 做正则表达式模式匹配,区分字符大小写。~*:对 URI 做正则表达式模式匹配,不区分字符大小写。不带符号:匹配起始于此 uri 的所有的 url。
- 匹配优先级:
=>^~>~/~*>不带符号
Apache 和 Nginx 中关于 url 的区别¶
Apache:
- 指定网页文件的 本地目录,可以理解为 绝对路径
<Directory> "/var/www/html/images/"- 指定网页的 url 路径,以
DocumentRoot "/var/www/html"为根,可以理解为 相对路径
<Location "/images/">Nginx:
location /images/ { ... }就相当于 Apache 中的<Location "/images/">
index¶
- 设定默认主页,可用于
http,server,location index FILE;
error_page¶
- 指定状态码和对应的网页文件。
error_page CODE URL;- 示例:
error_page 404 /404.html;注意:/404.html中前面的/的起始路径为能被匹配到的路径。
五、模块¶
Nginx 是高度模块化的,下面介绍一些常用的模块。
ngx_http_access_module (IP 访问控制)¶
- 基于客户端 IP 做访问控制。默认策略为 access。
allow address | CIDR | unix: | all;deny address | CIDR | unix: | all;- 可用于
http,server,location,limit_except
示例:
1 | location / { |
ngx_http_auth_basic_module (用户访问控制)¶
- 实现基于用户的访问控制,使用 basic 机制进行用户认证。
auth_basic string_NAME | off;auth_basic_user_file FILE;
示例:
1 | location /admin/ { |
ngx_http_stub_status_module (状态页)¶
用于输出 nginx 的基本状态信息。
示例:
- 配置
1 | location = /basic_status { |
- 访问 status 页面。
1 | Active connections: 1050 |
Active connections:当前活动客户端连接数,包括等待连接。accepts:已经接受的客户端请求的总数。handled::已处理连接的总数。requests:客户端请求的总的数。Reading:nginx 正在读取请求报文首部的当前连接数。Writing:nginx 正在发送响应报文的当前连接数。Waiting:当前等待请求的空闲客户端连接数。
ngx_http_log_module (日志)¶
以指定的格式记录 access 日志。
示例配置:
1 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' |
- 变量含义:Nginx官网可以查看全部变量列表
remote_addr:客户端地址。remote_user:经过 Basic 认证的用户名。time_local:本地服务器时间。request:请求报文的请求方法和协议版本。status:响应码。body_bytes_sent:响应报文 body 部分的大小。http_referer:请求报文的引用页。http_user_agent:客户端使用的浏览器。http_x_forwarded_for:在作为被代理的服务器时,显示真正的客户端地址。
open_log_file_cache (缓存)¶
缓存各日志文件的元数据信息。
open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];max:缓存的最大文件描述符数量。inactive:设定活动时间范围。min_uses:设置的最小访问次数。结合起来的意思是,在inactive指定的时间范围内,最少要访问这个次数,不然被认为是无效缓存。valid:验正缓存中各缓存项是否为活动项的时间间隔。
ngx_http_gzip_module (压缩)¶
压缩模块。
gzip on | off:是否启用压缩。gzip_comp_level LEVEL:压缩比。gzip_disable_regex:指定一个正则表达式,被正则表达式匹配到的$http-user-agent,将关闭压缩功能。gzip_min_length LENGTH:启用压缩功能的最小阈值。gzip_buffers NUMBER SIZE:支持实现压缩功能时为其配置的缓冲区数量及每个缓存区的大小。gzip_proxied:设置 nginx 作为代理服务器时,接收到从被代理服务器发送的响应报文后,在何种条件下启用压缩功能。gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any;off:对所有代理的请求不启用压缩。no-cache, no-store, private:表示从被代理服务器收到的响应报文首部的Cache-Control的值为此三者中任何一个,则启用压缩功能。any:全部压缩
gzip_types:压缩过滤器,仅对此处设定的 MIME 类型的内容启用压缩功能。gzip_types mime-type ...;
示例:
1 | gzip on; |
ngx_http_ssl_module (SSL)¶
加密 SSL 模块。
ssl on | off;:是否开启 ssl。ssl_certificate file;:指定当前虚拟主机使用 PEM 格式的证书文件。ssl_certificate_key file;:指定当前虚拟主机上与其证书匹配的私钥文件。ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];:支持 ssl 协议版本,默认为后三个。ssl_session_cache off | none | [builtin[:size]] [shared:name:size];:配置 ssl 缓存。builtin[:size]:使用 OpenSSL 内建的缓存,此缓存为每 worker 进程私有。[shared:name:size]:在各 worker 之间使用一个共享的缓存。
ssl_session_timeout time;:客户端一侧的连接可以复用ssl session cache中缓存的ssl参数的有效时长。
配置示例:
1 | server { |
ngx_http_rewrite_module (URL重定向)¶
使用正则表达式来检查请求的 RUI 地址,然后进行 URL 替换。
- 语法:
rewrite regex replacement [flag]; - 将用户请求的 URI 基于
regex所描述的模式进行检查,匹配到时将其替换为replacement。 [flag]:如果在同一级配置块中存在多个 rewrite 规则,那么会自上而下逐个检查。被某条件规则替换完成后,会重新一轮的替换检查,因此,使用[flag]标志位来控制此循环机制。- 如果
replacement是以http://或https://开头,则替换结果会直接以 永久重定向 返回给客户端。
flag 可用参数¶
last:重写完成后停止对当前 URI 在当前 location 中后续的其它重写操作,而后对新的 URI 启动新一轮重写检查,客户端对此无感知。即:提前重启新一轮循环(continue)
break:重写完成后停止对当前 URI 在当前 location 中后续的其它重写操作,而后直接跳转至重写规则配置块之后的其它配置,客户端对此无感知。即:结束循环(break)
redirect:重写完成后以 临时重定向 方式直接返回重写后生成的新 URI 给客户端,由客户端重新发起请求。
- 不能以
http://或https://开头。否则就是 永久重定向 了; - 默认状态码 302
permanent:重写完成后以 永久重定向 方式直接返回重写后生成的新 URI 给客户端,由客户端重新发起请求。
- 默认状态码 301
return:停止处理并将指定的代码或 URL 返回给客户端。
return code [text];return code URL;return URL;
其他参数¶
rewrite_log:是否开启重写日志。
rewrite_log on | off;
if:引入一个新的配置上下文。当条件满足时,执行配置块中的配置指令。
- 可用配置段:
server,location if (condition) { ... }condition- 比较操作符:
==:等于。!=:不等于。~:模式匹配,区分字符大小写。~*:模式匹配,不区分字符大小写。!~:模式不匹配,区分字符大小写。!~*:模式不匹配,不区分字符大小写。
- 文件及目录存在性判断:
-e,!-e:文件存在与否。-f,!-f:是否为空文件。-d,!-d:是否为目录。-x,!-x:是否为可执行文件。
set:设定用户自定义变量。
- 比较操作符:
set $variable value;
ngx_http_referer_module (防盗链)¶
当报文首部 Referer 字段中具有非法值时,阻止此次请求。(可用于防盗链)
valid_referers none | blocked | server_names | string ...;
定义 referer 首部的合法可用值:
none:请求报文首部没有 referer 首部。blocked:请求报文的 referer 首部没有值。server_names:参数,其可以有值作为主机名或主机名模式。arbitrary_string:直接字符串,但可使用*作通配符。regular expression:被指定的正则表达式模式匹配到的字符串。- 要使用
~打头,例如~.*\.monster\.com;
- 要使用
配置示例:
1 | valid_referers none block server_names *.monster.com *.mageedu.com monster.* mageedu.* ~\.monster\.; |
