定义
Nginx 是一个高性能的 HTTP 服务器、反向代理服务器以及邮件代理服务器。它以高并发、高吞吐量、低内存消耗而著称,常用于静态资源服务、负载均衡、反向代理和缓存等场景。
至于为什么要用代理服务器,请看:代理服务器
主要功能
- HTTP 服务器:Nginx 可以作为静态文件服务器,直接提供 HTML、CSS、JavaScript、图片等文件。它非常高效,适合用作前端项目的静态资源托管服务器。
- 反向代理:Nginx 可以将客户端的请求转发给后端服务器(如 Node.js、Python、Java 应用),起到代理作用,同时隐藏后端服务器,提升安全性。
- 负载均衡:Nginx 可以将请求分发到多个后端服务器(负载均衡),根据服务器的健康状态和负载情况,自动选择合适的服务器处理请求。
- 缓存功能:Nginx 可以缓存后端服务器返回的响应,提高重复请求的处理效率,减少后端服务器的压力。
- SSL/TLS 加密:Nginx 可以处理 HTTPS 请求,支持 SSL/TLS 协议,提供安全的网络通信。
预定义变量
客户端信息
- $remote_addr:客户端 IP 地址。
- $remote_port:客户端端口号。
- $remote_user:已经认证的客户端用户名(如 HTTP 基本认证)。
- $http_user_agent:客户端的 User-Agent 信息。
- $http_referer:HTTP 请求头中的 Referer 信息。
请求信息
- $request:请求的完整行(例如 GET /index.html HTTP/1.1)。
- $request_uri:原始请求的 URI,包括请求参数(例如 /index.html?query=1)。
- $uri:请求的 URI,但不包含参数,且可能已被 location 重写。
- $args:请求的参数部分(即 ? 之后的部分)。
- $request_method:请求方法(如 GET、POST)。
- $query_string:请求的查询字符串(与 $args 相同)。
- $http_<header_name>:访问请求头信息。例如,$http_host 用于获取请求头中的 Host 信息。
响应信息
- $status:响应的 HTTP 状态码。
- $sent_http_<header_name>:自定义响应头的信息。可以通过这种方式在配置中指定和修改响应头。
服务器信息
- $server_addr:服务器地址,Nginx 尝试解析配置的地址,但此变量可能影响性能。
- $server_name:处理请求的服务器名称。
- $server_port:请求到达的服务器端口。
连接信息
- $connection:当前连接的序列号。
- $connection_requests:当前连接已经处理的请求数量。
文件路径
- $document_root:当前请求的 root 路径(文件系统中的路径)。
- $realpath_root:当前请求的真实路径,即解析符号链接后的路径。
- $request_filename:当前请求的完整文件路径。
其他
- $hostname:Nginx 服务器的主机名。
- $binary_remote_addr:客户端 IP 的二进制表示(用于哈希计算)。
- $time_local:请求的本地时间。
- $msec:当前时间的 Unix 时间戳(毫秒级)。
- $scheme:请求使用的协议(如 http 或 https)。
配置项
全局配置
这些配置位于 nginx.conf 文件的最外层,影响整个 Nginx 的行为。
worker_processes
- 定义:Nginx 启动的工作进程数,一般设置为服务器的 CPU 核心数,或者使用 auto 让 Nginx 自动优化。
- 用法:
worker processes auto;
error_log
- 定义:指定错误日志文件和日志级别。
- 用法:
error_log /var/log/nginx/error.log warn;
pid
- 定义:指定保存 Nginx 进程 ID 的文件路径。
- 用法:
pid /var/run/nginx.pid;
events 模块配置
worker_connections
- 定义:每个工作进程允许的最大连接数。
- 用法:
events {
worker_connections 1024;
multi_accept: on;
}
multi_accept
- 定义:当设置为 on 时,每个工作进程会一次性接受尽可能多的连接,这可以提高请求处理效率。默认为 off。
- 用法:
events {
worker_connections 1024;
multi_accept: on;
}
use
- 定义:用于指定事件模型(如 epoll、kqueue、select 等),Nginx 会根据操作系统自动选择最优的事件模型。
- 用法:
events {
use: epoll;
}
accept_mutex
- 定义:用于启用“接受互斥锁”,防止多个工作进程同时接受请求,避免竞争,提升负载均衡。默认值为 on。
- 用法:
events {
accept_mutex: on;
}
worker_aio_requests
- 定义:用于设置异步 I/O 的最大请求数(主要用于文件操作)。
- 用法:
events {
worker_aio_requests 1024;
}
http 模块配置
http 模块是处理 HTTP 请求的核心模块,定义了如何处理客户端请求。
server
- 定义:定义一个虚拟主机块。一个 Nginx 实例可以有多个 server 块,每个块定义一个虚拟主机。
- 用法:
server {
listen 80;
server_name example.com;
root /var/www/html;
}
location
- 定义:匹配 URL 路径的处理规则。不同的路径可以有不同的处理方式。比如代理、文件服务等。
- 用法:
location / {
try_files $uri $uri/ =404;
}
try_files会尝试按照指定的顺序检查文件是否存在,并返回找到的第一个文件。如果所有指定的文件都不存在,try_files可以将请求重定向到另一个 URI 或返回一个指定的 HTTP 状态码。在这个例子中,当请求匹配到
/时,Nginx 会首先尝试直接返回请求的 URI 对应的文件(即$uri)。如果该文件不存在,Nginx 会尝试将请求作为目录处理,即在该目录下找到默认的索引文件(一般为index.html)。如果目录也不存在或没有默认索引文件,Nginx 最终会返回 404 状态码。
listen
- 定义:指定虚拟主机监听的端口,通常是 80(HTTP)或者 443(HTTPS)。
- 用法:
listen 80;
server_name
- 定义:指定虚拟主机的域名,支持通配符匹配。
- 用法:
server_name example.com www.example.com;
# server_name *.example.com;
root/alias
- 定义:root 设置根目录路径,alias 设置路径别名。alias 在匹配 location 时不会追加匹配的路径,而 root 会追加匹配路径。
:::success
root 指令允许你指定 Nginx 在文件系统中的哪个目录开始查找和返回请求的文件。这是处理静态文件(如 HTML、CSS、JavaScript、图片等)和可能的服务端脚本或程序的基础。
alias 指令用于映射请求的 URI 到一个确切的文件系统路径。它不会将请求的 URI 与指定路径拼接,而是直接替换掉 URI 中的部分或全部,以定位到具体的文件。
:::
- 用法:
location /static/ {
root /var/www/html;
}
:::info
在这个配置中,如果 Nginx 接收到一个对http://example.com/static/images/logo.png的请求,它会将/static/images/logo.png拼接到/var/www/html后面,形成/var/www/html/images/logo.png的完整文件路径,然后去尝试找到并返回该文件。
:::
location /some/path/ {
alias /path/to/actual/directory/;
}
:::info
在这个例子中,当请求以/some/path/开头时,Nginx 会将/some/path/部分替换为/path/to/actual/directory/,并在新的路径下查找资源。重要的是要注意alias路径末尾的斜杠,它会影响 Nginx 如何处理剩余的 URI 部分。
:::
alias 路径处理:
- 如果
location块中的 URI 以斜杠结尾(如/some/path/),则 Nginx 会在alias指定的路径后直接添加请求的剩余 URI 部分(不包括location块中指定的 URI 部分)来查找文件。 - 如果
location块中的 URI 不以斜杠结尾(如/some/file),则 Nginx 会将请求的最后一个部分(即最后一个/之后的部分)作为文件名,并在alias指定的路径下查找这个文件。
index
- 定义:指定当访问目录时,默认加载的文件。
- 用法:
index index.html index.htm;
gzip
- 定义:启用 gzip 压缩以提高传输效率
- 用法:
gzip on;
gzip_types text/plain application/javascript text/css;
client_max_body_size
- 定义:设置客户端请求的最大允许大小,常用于限制上传文件的大小。
- 用法:
client_max_body_size 50M;
反向代理配置
Nginx 常被用于反向代理,通过它可以将请求转发到后端服务器。
proxy_pass
- 定义:转发请求到后端服务器。
- 用法:
location /api/ {
proxy_pass http://localhost:3000/;
}
proxy_set_header
- 定义:在转发请求时,设置额外的 HTTP 请求头。
- 用法:
location /api/ {
proxy_pass http://localhost:3000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
proxy_redirect
- 定义:修改后端服务器返回的 Location 和 Refresh HTTP 响应头字段。这在你使用 Nginx 作为反向代理时特别有用,因为后端服务器返回的响应可能会包含指向其自身的 URL,而不是你希望客户端访问的公共 URL(即 Nginx 代理的 URL)。
关于 Location 和 Refresh 的更多内容,可以看:请求头和响应头
- 用法:
proxy_redirect http://backend.example.com/ http://example.com/;
负载均衡配置
Nginx 支持将请求分发到多个后端服务器,实现负载均衡。
upstream
- 定义:定义后端服务器组。
upstream name {
server address [parameters];
server address [parameters];
...
}
- 说明:
name:上游服务器组的名称,可以在proxy_pass指令中引用。address:上游服务器的地址,可以是 IP 地址和端口号,也可以是域名。parameters:可选参数,用于配置服务器的权重、最大失败次数、超时时间等。
- 用法:
http {
upstream myapp {
server 192.168.1.100:8080 weight=2;
server 192.168.1.101:8080;
server 192.168.1.102:8080 backup;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://myapp;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
复杂均衡策略
- 策略:轮询(默认),将请求依次分配给后端服务器。
parameters常用属性:weight:设置服务器的权重,默认为 1。权重越高,分配到的请求越多。max_fails:在指定的时间内,连接失败的最大次数。当超过这个次数时,Nginx 会认为该服务器不可用,并在一段时间内不再将请求转发到该服务器。fail_timeout:设置服务器不可用的时间。在这段时间内,Nginx 不会将请求转发到该服务器。一般与max_fails配合使用。backup:标记该服务器为备用服务器。当其他非备用服务器都不可用时,才会将请求转发到备用服务器。ip_hash:根据客户端的 IP 地址进行哈希计算,将同一客户端的请求始终转发到同一台上游服务器。这样可以保证同一客户端的会话保持在同一台服务器上。least_conn:将请求转发到连接数最少的上游服务器,实现基于最少连接数的负载均衡。
缓存策略
Nginx 支持配置代理缓存,用于缓存后端服务器的响应。
proxy_cache_path
- 定义:定义缓存路径和相关参数。
- 用法:
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off;
- 说明:
/data/nginx/cache:设置缓存的存储路径为/data/nginx/cache。所有被缓存的响应内容将存储在这个目录下。levels=1:2:定义缓存的目录层级结构。这里表示使用两级目录结构。例如,可能会生成类似于/data/nginx/cache/a/b的目录路径,其中a和b是根据缓存键动态生成的目录名称。keys_zone=my_cache:10m:创建一个名为my_cache的缓存区,大小为 10MB。这个缓存区用于存储缓存的元数据,如缓存键、缓存的过期时间等信息。max_size=1g:设置整个缓存的最大尺寸为 1GB。当缓存的总大小超过这个限制时,Nginx 会根据缓存的策略(如inactive参数定义的策略)来清理一些缓存内容,以保持缓存的总大小在这个限制之内。inactive=60m:如果一个缓存项在 60 分钟内没有被访问,那么它将被视为不活跃,并可能被清理。use_temp_path=off:关闭临时路径的使用。通常,Nginx 在缓存文件时可能会先将文件存储在临时路径中,然后再移动到最终的缓存路径。设置这个参数为off可以避免使用临时路径,直接将缓存文件存储到指定的缓存路径中,提高缓存的效率。
proxy_cache
- 定义:启用缓存,制定缓存区。
- 用法:
location / {
proxy_cache my_cache;
proxy_pass http://backend;
}
SSL 配置
Nginx 支持 HTTPS,配置 SSL 可以提升安全性。
ssl_certificate / ssl_certificate_key
- 定义:指定 SSL 证书和秘钥。
- 用法:
server {
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
}
ssl_protocols
- 定义:指定支持的 SSL/TLS 协议。
- 用法:
ssl_protocols TLSv1.2 TLSv1.3;
日志相关配置
access_log
- 定义:指定访问日志文件路径和格式。
- 用法:
# log_format 用于定义日志格式
log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer
access_log /var/log/nginx/access.log myFormat;
示例
来源:稀土掘金
# 全局段配置
# ------------------------------
# 指定运行nginx的用户或用户组,默认为nobody。
#user administrator administrators;
# 设置工作进程数,通常设置为等于CPU核心数。
#worker_processes 2;
# 指定nginx进程的PID文件存放位置。
#pid /nginx/pid/nginx.pid;
# 指定错误日志的存放路径和日志级别。
error_log log/error.log debug;
# events段配置信息
# ------------------------------
events {
# 设置网络连接序列化,用于防止多个进程同时接受到新连接的情况,这种情况称为"惊群"。
accept_mutex on;
# 设置一个进程是否可以同时接受多个新连接。
multi_accept on;
# 设置工作进程的最大连接数。
worker_connections 1024;
}
# http配置段,用于配置HTTP服务器的参数。
# ------------------------------
http {
# 包含文件扩展名与MIME类型的映射。
include mime.types;
# 设置默认的MIME类型。
default_type application/octet-stream;
# 定义日志格式。
log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for';
# 指定访问日志的存放路径和使用的格式。
access_log log/access.log myFormat;
# 允许使用sendfile方式传输文件。
sendfile on;
# 限制每次调用sendfile传输的数据量。
sendfile_max_chunk 100k;
# 设置连接的保持时间。
keepalive_timeout 65;
# 定义一个上游服务器组。
upstream mysvr {
server 127.0.0.1:7878;
server 192.168.10.121:3333 backup; #此服务器为备份服务器。
}
# 定义错误页面的重定向地址。
error_page 404 https://www.baidu.com;
# 定义一个虚拟主机。
server {
# 设置单个连接上的最大请求次数。
keepalive_requests 120;
# 设置监听的端口和地址。
listen 4545;
server_name 127.0.0.1;
# 定义location块,用于匹配特定的请求URI。
location ~*^.+$ {
# 设置请求的根目录。
#root path;
# 设置默认页面。
#index vv.txt;
# 将请求转发到上游服务器组。
proxy_pass http://mysvr;
# 定义访问控制规则。
deny 127.0.0.1;
allow 172.18.5.54;
}
}
}
一些说明:
sendfile
- 定义:
sendfile是一种高效的文件传输方式,用于在操作系统层面直接将文件内容从磁盘传输到网络接口,绕过用户空间。它主要用于提高数据传输性能,特别是在处理大文件的场景下。 - 工作原理:
- 传统的文件传输过程通常需要以下步骤:
- 将文件从磁盘读取到内核空间。
- 将内核空间的数据拷贝到用户空间。
- 用户空间将数据发送到网络接口。
sendfile函数的作用是在内核空间中直接完成文件到网络套接字的传输,避免了数据从内核空间到用户空间的多次拷贝,从而减少了上下文切换和系统开销。整个过程简化为:直接将文件数据从内核空间传输到网络接口,无需经过用户空间。
- 传统的文件传输过程通常需要以下步骤:
location 路径映射详解
:::warning
以下格式用法在 nginx 均适用,例如:
:::
if ($request_uri ~ ^/_proxy/(.*)){
set $backend_host http://$1;
}
如果请求的 URI 匹配^/_proxy/(.*)这个正则表达式,那么就将 $1 设置为变量$backend_host的值,
- 格式:
location [ = | ~ | ~* | !~ | !~* | ^~ | @ ] uri {...}
- 各标识符解释:
=:精确匹配。如果匹配成功,立即停止搜索并处理此请求。~:执行正则匹配,区分大小写。~*:执行正则匹配,不区分大小写。!~:正则匹配,区分大小写不匹配。!~*:正则匹配,不区分大小写不匹配。^~:前缀匹配。如果匹配成功,不再匹配其他location,且不查询正则表达式。@:指定命名的location,主要用于内部重定向请求,如error_page和try_files。uri:待匹配的请求字符串。可以是普通字符串或包含正则表达式。
- 优先级:优先级顺序:无特定标识 <
^~<=< 正则匹配 (~,~*,!~,!~*) - 示例:
location = / {
# 精确匹配 /,主机名后面不能带任何字符串
# http://abc.com [匹配成功]
# http://abc.com/index [匹配失败]
}
location ^~ /img/ {
# 以 /img/ 开头的请求,都会匹配上
# http://abc.com/img/a.jpg [匹配成功]
# http://abc.com/img/b.mp4 [匹配成功]
}
location ~* /Example/ {
# 忽略 uri 部分的大小写
# http://abc.com/test/Example/ [匹配成功]
# http://abc.com/example/ [匹配成功]
}
location /documents {
# 如果有正则表达式可以匹配,则优先匹配正则表达式
# http://abc.com/documentsabc [匹配成功]
}
location / {
# http://abc.com/abc [匹配成功]
}
动静分离
- 概念:动静分离是指将动态内容和静态内容分开处理。静态内容通常包括:图片、CSS、JavaScript、HTML 文件等,这些内容不需要经常更改。而动态内容则是经常变化的,如:PHP、ASP、JSP、Servlet 等生成的内容。
- 配置:
- 设置根目录
location ~* .(jpg|jpeg|png|gif|ico|css|js)$ {
root /path/to/static/files;
expires 30d; # 设置缓存时间
}
在上述配置中,所有的静态文件都被存放在/path/to/static/files目录下。expires指令设置了静态文件的缓存时间。
- 使用 alias 别名
location /static/ {
alias /path/to/static/files/;
}
在这个配置中,URL 中的/static/会映射到文件系统的/path/to/static/files/。
- 代理动态内容
location / {
proxy_pass http://backend_server_address;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
- 注意事项:
- 确保你的静态文件路径配置正确,避免 404 错误。
- 使用
expires指令为静态内容设置缓存,这可以减少服务器的负载并提高页面加载速度。 - 动静分离不仅可以提高服务器的响应速度,还可以减少后端服务器的压力,因为静态文件通常由 Nginx 直接处理,而不需要代理到后端服务器。
防盗链

防盗链是指防止其他网站直接链接到你的网站资源(如图片、视频等),从而消耗你的服务器带宽。Nginx 提供了一个非常方便的模块——
ngx_http_referer_module,用于实现防盗链功能。
- 基本配置:
location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$ {
valid_referers none blocked www.example.com example.com *.example.net;
if ($invalid_referer) {
return 403;
}
}
- 说明:
valid_referers定义了合法的来源页面。none表示直接访问,blocked表示没有Referer头的访问,www.example.com和example.com是合法的来源域名,*.example.net表示example.net的所有子域名都是合法的来源。$invalid_referer变量会在来源不在valid_referers列表中时变为”true”。- 如果来源不合法,服务器将返回 403 禁止访问的状态码。
- 注意事项:
- 防盗链配置可能会影响搜索引擎的爬虫,因此在实施防盗链策略时要小心。
- 如果你的网站使用了 CDN,确保 CDN 的服务器也在
valid_referers列表中,否则 CDN 可能无法正常工作。 - 为了确保防盗链配置正确,你应该在生产环境之前在测试环境中进行充分的测试。