入门
基本配置
Nginx 配置使用分层块结构。worker_processes 设置进程数。http 块包含 server 块,server 块包含 location 块。重载前务必用 nginx -t 测试。
# /etc/nginx/nginx.conf
worker_processes auto;
events {
worker_connections 1024;
}
http {
server {
listen 80;
server_name example.com;
location / {
root /var/www/html;
index index.html;
}
}
}
# Test config: nginx -t
# Reload: nginx -s reload
# Start: systemctl start nginx指令与上下文
上下文嵌套:main > events/http/mail > server > location。简单指令以分号结尾;块指令使用大括号。某些指令只在特定上下文中有效。
# Contexts are hierarchical blocks
# Global context (main) - outside any block
user nginx;
worker_processes auto;
# events context
events {
worker_connections 1024;
}
# http context
http {
# server context
server {
listen 80;
# location context
location / {
root /var/www/html;
}
}
}
# Directives: simple (name value;) or block (name { ... })测试与重载
nginx -t 检查语法并尝试打开引用的文件(证书、日志)。重载前务必运行。reload 发送 SIGHUP——worker 完成当前请求后重载。restart 会导致短暂停机。
# test configuration for syntax errors
nginx -t
# test and print full config
nginx -T
# reload config without dropping connections
nginx -s reload
# stop gracefully (finishes current requests)
nginx -s quit
# stop immediately
nginx -s stop
# reopen log files (after log rotation)
nginx -s reopen
# systemd alternative
systemctl reload nginx
systemctl restart nginxMain 与 HTTP 上下文
worker_processes 和 events 位于 main 上下文。路由、代理、缓存和 server 块位于 http。SSL、日志和 gzip 可在 http 中设置并被 server/location 继承。
# main context - global settings
user nginx;
worker_processes auto;
worker_rlimit_nofile 65535;
pid /var/run/nginx.pid;
events {
worker_connections 4096;
}
http {
# all HTTP-related config lives here
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
}包含文件
include 保持配置模块化。conf.d 通配符(*.conf)是现代约定。sites-enabled 配合符号链接是 Debian/Ubuntu 的模式。mime.types 将文件扩展名映射到 Content-Type。
# main config: /etc/nginx/nginx.conf
http {
include /etc/nginx/mime.types;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
# /etc/nginx/conf.d/default.conf
server {
listen 80;
server_name example.com;
root /var/www/html;
}
# Disable a site: remove the file from sites-enabled/
# Available sites kept in sites-available/, symlinked into enabled/命令行操作
nginx -V 显示编译时选项,包括内置了哪些模块。-g 设置 覆盖配置的指令。-c 用于在不改动默认配置的情况下测试备用配置。
# start nginx (if not managed by systemd)
nginx
# specify a custom config file
nginx -c /path/to/nginx.conf
# set a global directive from command line
nginx -g "worker_processes 4;"
# test config
nginx -t
# print version and build configuration
nginx -V
# send signal to master process
nginx -s reload
nginx -s stop服务器块
基本服务器块
server 块定义一个虚拟主机。listen 设置端口。server_name 匹配 Host 头。root 设置文档根目录。index 指定目录请求时提供哪些文件。
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}多个服务器名
Nginx 按精确匹配、通配符(*.foo.com)、正则的顺序匹配 server_name。第一个匹配的 server 块处理请求。在同一端口上为不同应用使用不同的块。
server {
listen 80;
server_name example.com www.example.com;
# ...
}
server {
listen 80;
server_name api.example.com;
# ...
}
# Wildcard: matches any single-level subdomain
server_name *.example.com;
# Regex (starts with ~)
server_name ~^www\d+\.example\.com$;默认服务器
default_server 处理 Host 头不匹配任何 server_name 的请求。下划线是一种约定(无效主机名,永不匹配真实流量)。return 444 不返回响应直接关闭连接。
# mark a server block as default for the port
server {
listen 80 default_server;
server_name _;
return 444; # drop connection (no response)
}
# handles all requests that don't match another server_name
# _ is an invalid hostname, used as catch-all convention
# useful to block requests with no matching Host headerlisten 指令
listen 可以绑定到特定地址、IPv6、UNIX socket,或设置 default_server。ssl 参数为该监听器启用 TLS。一个 server 块中允许多个 listen 指令。
# listen on port 80
listen 80;
# IPv6
listen [::]:80;
# HTTPS (ssl flag)
listen 443 ssl;
listen [::]:443 ssl;
# specific address
listen 127.0.0.1:8080;
# default server for this port
listen 80 default_server;
# listen on UNIX socket
listen unix:/var/run/nginx.sock;服务器名匹配
匹配优先级为精确 > 前导通配符 > 后置通配符 > 正则。正则按配置顺序检查,因此第一个匹配生效。如果 server 名很长或很多,请增大哈希桶大小。
# Order of precedence (highest to lowest):
# 1. Exact name: example.com
# 2. Longest wildcard starting with *: *.example.com
# 3. Longest wildcard ending with *: www.*
# 4. First matching regex (in config order): ~^www\d+\.
# If nothing matches, the default_server handles it
# Tune hash sizes for many server names
http {
server_names_hash_bucket_size 64;
server_names_hash_max_size 512;
}全捕获服务器
全捕获服务器防止带有任意 Host 头的请求到达你的应用。return 301 重定向到已知主机。return 444 直接断开连 接,适用于抵御直接访问你 IP 的扫描器。
# catch all requests regardless of host header
server {
listen 80 default_server;
server_name _; # invalid name, never matches real host
return 301 https://$host$request_uri;
}
# or drop the connection silently
server {
listen 80 default_server;
server_name _;
return 444;
}
# redirect unknown subdomains to main site
server {
listen 80 default_server;
return 301 https://example.com;
}Location 块
Location 修饰符
修饰符改变匹配行为:=(精确)、^~(前缀,跳过正则)、~(区分大小写正则)、~*(不区分大小写正则)、无(前缀)。正则适合文件扩展名;前缀适合路径树。
# exact match - fastest, stops search if matched
location = /favicon.ico {
log_not_found off;
}
# prefix match with ^~ - skips regex if longest prefix matches
location ^~ /static/ {
root /var/www;
}
# case-sensitive regex
location ~ \.php$ {
fastcgi_pass unix:/run/php/php-fpm.sock;
}
# case-insensitive regex
location ~* \.(jpg|jpeg|png|gif|ico)$ {
expires 30d;
}
# prefix match (no modifier)
location / {
try_files $uri $uri/ /index.php;
}Location 优先级
Nginx 先评估精确(=),然后前缀匹配(最长优先),然后按配置顺序的正则。^~ 使前缀匹配跳过正则评估。理解此顺序可避免重叠 location 的意外。
# Priority order (highest to lowest):
# 1. = exact match
# 2. ^~ prefix match (skips regex if matched)
# 3. ~ ~* regex (first match in config order)
# 4. (none) prefix match (longest wins)
location = /api {
# exact, highest priority
}
location ^~ /assets/ {
# prefix, beats regex
}
location ~ \.php$ {
# regex
}
location /api/ {
# prefix, lowest of these
}root 与 alias
root 将 URI 追加到其值后;alias 替换匹配的前缀。当 location 映射到目录树的子目录时用 root。当 URI 路径与文件系统路径不同时用 alias。alias 配合正则需要 $1 捕获。
# root: appends the full URI to the path
# request /img/cat.png -> /var/www/img/cat.png
location /img/ {
root /var/www;
}
# alias: replaces the matched location part
# request /img/cat.png -> /data/images/cat.png
location /img/ {
alias /data/images/;
}
# alias with regex requires capturing the path
location ~ ^/img/(.*)$ {
alias /data/images/$1;
}try_files 指令
try_files 按顺序检查每个参数;最后一个是回退(不检查文件)。$uri 检查文件,$uri/ 检查目录。回退可以是 URI、=code 或 @named。对 SPA 和 CMS 路由至关重要。
# try files in order, fall back to last option
location / {
try_files $uri $uri/ /index.html;
}
# serve index.php if file/dir not found (pretty URLs)
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# return 404 if nothing matches
location / {
try_files $uri =404;
}
# named location as fallback
location / {
try_files $uri $uri/ @drupal;
}命名 Location
命名 location(@name)是内部专用的——永远不会被请求 URI 直接匹配。它们是 try_files、error_page 和 rewrite 的目标。适合在多个 location 间共享配置块(如回退处理器)。
# named locations start with @, can't be reached externally
# used as try_files fallback or rewrite target
location / {
try_files $uri $uri/ @app;
}
location @app {
fastcgi_pass unix:/run/php.sock;
# ... fastcgi config
}
# useful for organizing common error logic
location @error_page {
return 500 "Internal Server Error";
}
# can also be used with error_page
error_page 404 @fallback;
location @fallback {
proxy_pass http://backend;
}嵌套 Location
location 可以嵌套。内部 location 继承并可以覆盖外部 location 的指令。适用于在更宽泛的前缀内特殊处理某个路径(例如上传端点设置更大的 body 大小,或从某个子路径提供静态文件)。
location /api {
# /api/users, /api/posts handled here
proxy_pass http://backend;
location /api/upload {
# override for upload endpoint
client_max_body_size 50M;
proxy_pass http://upload_backend;
}
location ~ ^/api/static/(.*)$ {
# regex inside prefix location
root /var/www;
}
}反向代理
基本 proxy_pass
proxy_pass 将请求转发到上游服务器。proxy_pass 末尾的斜杠会导致匹配的 location 前缀被替换。没有末尾斜杠时,原始 URI 原样传递。
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://localhost:3000;
}
}
# proxy_pass with URI replacement (trailing slash matters)
location /api/ {
proxy_pass http://backend/; # /api/foo -> /foo
}
# without trailing slash, URI is preserved
location /api/ {
proxy_pass http://backend; # /api/foo -> /api/foo
}代理头
默认 nginx 不传递客户端 IP 或原始主机。设置 X-Real-IP 和 X-Forwarded-For 让后端识别真实客户端。X-Forwarded-Proto 告知原始协议,对 HTTPS 重定向逻辑至关重要。
location / {
proxy_pass http://backend;
# preserve original host
proxy_set_header Host $host;
# real client IP (not nginx's)
proxy_set_header X-Real-IP $remote_addr;
# forwarded-for chain
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# scheme (http or https)
proxy_set_header X-Forwarded-Proto $scheme;
# original host
proxy_set_header X-Forwarded-Host $host;
}Upstream 代理
upstream 块定义一个命名的服务器池,供 proxy_pass 引用。这实现了负载均衡、健康检查和 keepalive 连接。upstream 变量可用于记录哪个后端处理了每个请求。
# define a named pool of backend servers
upstream backend {
server 10.0.0.1:8080;
server 10.0.0.2:8080;
server 10.0.0.3:8080;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
# useful upstream variables:
# $upstream_addr, $upstream_status,
# $upstream_response_time, $upstream_cache_status代理超时
proxy_connect_timeout 是 TCP 握手限制;读/写超时适用于数据传输期间的空闲期。为慢端点(导出、AI 推理)增大 read_timeout。upstream keepalive 复用连接以降低延迟。
location / {
proxy_pass http://backend;
# connect timeout (TCP handshake to upstream)
proxy_connect_timeout 5s;
# time between reads from upstream (response)
proxy_read_timeout 60s;
# time between writes to upstream (request body)
proxy_send_timeout 60s;
# for slow backends (large uploads/downloads)
proxy_read_timeout 300s;
}
# keepalive connections to upstream
upstream backend {
server 10.0.0.1:8080;
keepalive 32;
}代理缓冲
缓冲将上游响应存储在内存/磁盘后再发送给客户端——对慢客户端高效但会破坏流式传输。对 SSE、WebSocket 或分块流式传输请关闭。buffer_size 是第一部分(头);buffers 持有其余部分。
location / {
proxy_pass http://backend;
# enable buffering (default on)
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
# busy buffers during streaming
proxy_busy_buffers_size 16k;
# disable for streaming/SSE
proxy_buffering off;
proxy_cache off;
}
# Server-Sent Events or streaming responses
location /events {
proxy_pass http://backend;
proxy_buffering off;
proxy_cache off;
chunked_transfer_encoding on;
}WebSocket 升级
WebSocket 需要 HTTP/1.1 加上 Upgrade 和 Connection 头。map 块将 Upgrade 头转换为正确的 Connection 值(upgrade 对 close)。较长的 proxy_read_timeout 防止空闲 WebSocket 被关闭。
# Map the Upgrade header to a Connection value
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
location /ws {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# keepalive for long-lived connections
proxy_read_timeout 3600s;
}
}负载均衡
Upstream 块
upstream 块定义后端服务器。默认负载均衡是轮询。max_fails 和 fail_timeout 配置被动健康检查:在 fail_timeout 内失败 max_fails 次后,服务器被标记为下线 fail_timeout 秒。
upstream backend {
server backend1.example.com weight=5;
server backend2.example.com;
server backend3.example.com max_fails=3 fail_timeout=30s;
}
server {
location / {
proxy_pass http://backend;
}
}
# default algorithm: round-robin
# max_fails: failed attempts before marking server down
# fail_timeout: window for counting fails AND downtime duration负载均衡方法
round-robin 均匀分配;least_conn 发送给负载最低的服务器;ip_hash 让客户端保持在同一服务器(通过 IP 实现粘性会话);hash 按自定义键分配。consistent 参数在增删服务器时最小化重分布。