Nginx 高级配置
掌握 Nginx 的高级配置选项和特性
Nginx 重写规则 (rewrite)
rewrite 指令用于修改请求的 URI,支持正则表达式匹配和重定向。
基本语法
rewrite regex replacement [flag];
常用标志
- last - 停止处理当前 rewrite 指令,开始搜索与新 URI 匹配的 location
- break - 停止处理当前 rewrite 指令,继续执行当前 location 块中的其他指令
- redirect - 返回 302 临时重定向
- permanent - 返回 301 永久重定向
rewrite 示例
server {
listen 80;
server_name example.com;
# 将 HTTP 重定向到 HTTPS
rewrite ^ https://$server_name$request_uri? permanent;
# 移除 URL 中的 www 前缀
server_name www.example.com example.com;
if ($host = 'www.example.com') {
rewrite ^ https://example.com$request_uri? permanent;
}
# 重写友好 URL
location / {
rewrite ^/products/([0-9]+)/?$ /product.php?id=$1 last;
rewrite ^/categories/([a-z]+)/?$ /category.php?name=$1 last;
}
}
访问控制配置
基于 IP 的访问控制
server {
listen 80;
server_name example.com;
# 允许特定 IP 访问
location /admin {
allow 192.168.1.1;
allow 10.0.0.0/24;
deny all;
root /var/www/admin;
index index.html;
}
# 禁止特定 IP 访问
location /private {
deny 192.168.1.100;
allow all;
root /var/www/private;
index index.html;
}
}
基于密码的访问控制
server {
listen 80;
server_name example.com;
# 密码保护目录
location /secure {
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;
root /var/www/secure;
index index.html;
}
}
创建密码文件
使用 htpasswd 命令创建密码文件:
# 安装 apache2-utils(包含 htpasswd 命令)
sudo apt install apache2-utils # Ubuntu/Debian
sudo yum install httpd-tools # CentOS/RHEL
# 创建密码文件并添加用户
sudo htpasswd -c /etc/nginx/.htpasswd admin
# 添加新用户(不覆盖现有文件)
sudo htpasswd /etc/nginx/.htpasswd user1
# 查看密码文件内容
cat /etc/nginx/.htpasswd
Nginx 缓存配置
代理缓存配置
http {
# 配置代理缓存
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://localhost:3000;
proxy_cache my_cache;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_key "$scheme$request_method$host$request_uri";
add_header X-Cache-Status $upstream_cache_status;
}
}
}
FastCGI 缓存配置(用于 PHP)
http {
# 配置 FastCGI 缓存
fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=fastcgi_cache:10m max_size=10g inactive=60m use_temp_path=off;
server {
listen 80;
server_name example.com;
root /var/www/html;
index index.php;
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# 启用 FastCGI 缓存
fastcgi_cache fastcgi_cache;
fastcgi_cache_valid 200 60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
add_header X-FastCGI-Cache $upstream_cache_status;
}
}
}
缓存清除
可以使用第三方模块如 ngx_cache_purge 来实现缓存清除功能:
http {
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;
server {
listen 80;
server_name example.com;
# 缓存清除配置
location ~ /purge(/.*) {
allow 127.0.0.1;
deny all;
proxy_cache_purge my_cache "$scheme$request_method$host$1";
}
location / {
proxy_pass http://localhost:3000;
proxy_cache my_cache;
# 其他缓存配置...
}
}
}
Nginx 限流配置
基于连接的限流
http {
# 配置连接限制区域
limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
server {
listen 80;
server_name example.com;
# 限制每个 IP 的并发连接数
location / {
limit_conn conn_limit_per_ip 10;
root /var/www/html;
index index.html;
}
}
}
基于请求的限流
http {
# 配置请求限制区域
limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=10r/s;
server {
listen 80;
server_name example.com;
# 限制每个 IP 的请求速率
location /api {
limit_req zone=req_limit_per_ip burst=20 nodelay;
proxy_pass http://localhost:3000;
}
}
}
限流参数说明
- rate - 允许的请求速率,如 10r/s(每秒 10 个请求)
- burst - 允许的突发请求数,超过 rate 的请求会被放入队列
- nodelay - 当队列满时,直接返回错误而不是延迟处理
Nginx 变量和映射
内置变量
Nginx 提供了许多内置变量,可以在配置中使用:
$host # 请求的主机名
$server_name # 配置文件中定义的服务器名
$request_uri # 完整的请求 URI,包括查询字符串
$uri # 请求的 URI,不包括查询字符串
$args # 请求的查询字符串
$remote_addr # 客户端 IP 地址
$remote_port # 客户端端口
$server_addr # 服务器 IP 地址
$server_port # 服务器端口
$scheme # 请求协议(http 或 https)
$request_method # 请求方法(GET, POST 等)
$status # 响应状态码
$body_bytes_sent # 发送的响应体字节数
$http_user_agent # 客户端 User-Agent
$http_referer # 请求的 Referer 头
使用 map 指令
map 指令用于创建变量映射,基于一个变量的值设置另一个变量的值:
http {
# 配置用户代理映射
map $http_user_agent $is_mobile {
default 0;
~*mobile 1;
~*android 1;
~*iphone 1;
~*ipad 1;
}
# 配置国家映射(基于 IP)
map $remote_addr $country {
default unknown;
192.168.1.0/24 cn;
10.0.0.0/24 local;
}
server {
listen 80;
server_name example.com;
location / {
# 根据设备类型提供不同内容
if ($is_mobile) {
rewrite ^ /mobile$request_uri? last;
}
root /var/www/html;
index index.html;
}
location /mobile {
root /var/www;
index index.html;
}
}
}
Nginx 高级模块配置
启用 Gzip 压缩
http {
# Gzip 压缩配置
gzip on;
gzip_comp_level 6;
gzip_min_length 1000;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_vary on;
gzip_proxied any;
gzip_disable "MSIE [1-6]\.";
# 其他配置...
}
启用 Brotli 压缩(需要安装模块)
http {
# Brotli 压缩配置
brotli on;
brotli_comp_level 6;
brotli_min_length 1000;
brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# 其他配置...
}
配置 HTTP/2
server {
listen 443 ssl http2;
server_name example.com;
# SSL 配置
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# 其他配置...
}
Nginx 配置优化
工作进程配置
# 主配置文件顶部
user nginx;
# 设置为 CPU 核心数
worker_processes auto;
# 绑定工作进程到特定 CPU 核心
worker_cpu_affinity auto;
# 最大打开文件数
worker_rlimit_nofile 65536;
events {
# 每个工作进程的最大连接数
worker_connections 10240;
# 使用 epoll 事件模型(Linux)
use epoll;
# 允许多个连接同时接受
multi_accept on;
}
HTTP 核心优化
http {
# 隐藏 Nginx 版本号
server_tokens off;
# 启用 sendfile
sendfile on;
# 启用 tcp_nopush
tcp_nopush on;
# 启用 tcp_nodelay
tcp_nodelay on;
# 连接超时设置
keepalive_timeout 65;
keepalive_requests 100;
# 客户端请求体大小限制
client_max_body_size 1m;
# 缓冲区设置
client_body_buffer_size 16k;
client_header_buffer_size 1k;
large_client_header_buffers 4 8k;
# 其他配置...
}
实践练习
练习 1:配置 URL 重写
- 配置将 HTTP 重定向到 HTTPS
- 配置移除 URL 中的 www 前缀
- 配置友好的产品详情页 URL,如
/product/123重写到/product.php?id=123 - 测试重写规则是否生效
练习 2:配置访问控制
- 创建一个需要密码保护的目录
- 使用
htpasswd创建密码文件 - 配置基于 IP 的访问控制,只允许特定 IP 访问管理后台
- 测试访问控制是否生效
练习 3:配置缓存和限流
- 配置代理缓存,缓存后端 API 的响应
- 配置请求限流,限制每个 IP 的请求速率
- 测试缓存是否生效(检查响应头中的 X-Cache-Status)
- 测试限流是否生效(快速发送多个请求)
常见问题解答
Q: 如何调试 rewrite 规则?
A: 可以在配置中添加以下指令来启用 rewrite 日志:
http {
# 启用 rewrite 日志
rewrite_log on;
# 设置错误日志级别为 notice
error_log /var/log/nginx/error.log notice;
# 其他配置...
}
Q: 如何处理大文件上传?
A: 需要调整客户端请求体大小限制:
http {
# 允许上传 100MB 的文件
client_max_body_size 100m;
# 其他配置...
}
Q: 如何配置 Nginx 作为文件服务器?
A: 可以使用 autoindex 指令启用目录浏览:
server {
listen 80;
server_name files.example.com;
root /var/www/files;
# 启用目录浏览
location / {
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
}
}