前言
Jym好😘,我是珑墨,今天给大家分享 【Nginx 】网站优化深度指南 ,嘎嘎的😍,看下面。
Nginx可以说是Web架构的核心服务,其配置优化直接影响网站的性能、安全性和用户体验。下面咱将从基础配置到前沿技术,全面介绍 Nginx 网站优化的实战方法,涵盖性能调优、安全加固、高可用部署等关键领域。
性能优化核心配置
1. Worker 进程优化
Nginx 采用多进程模型,合理配置 worker 进程数量是性能优化的基础。
# /etc/nginx/nginx.conf
# 主配置段
user nginx;
worker_processes auto; # 自动检测 CPU 核心数
worker_cpu_affinity auto; # CPU 亲和性绑定(Linux)
# 连接处理优化
worker_rlimit_nofile 65535; # 每个 worker 最大文件描述符数
events {
use epoll; # Linux 下使用 epoll 事件模型
worker_connections 8192; # 每个 worker 最大连接数
multi_accept on; # 一次 accept 多个连接
accept_mutex off; # 现代内核下关闭 accept 互斥锁
}
优化说明:
worker_processes auto:自动根据 CPU 核心数设置,避免过度配置worker_rlimit_nofile:提高文件描述符限制,支持更多并发连接use epoll:Linux 下高性能事件模型multi_accept on:减少系统调用次数,提升效率
2. 缓冲区优化
合理设置缓冲区大小,减少 I/O 操作,提升响应速度。
http {
# 基础缓冲区设置
client_body_buffer_size 128k;
client_header_buffer_size 1k;
large_client_header_buffers 4 16k;
# 响应缓冲区
output_buffers 1 32k;
postpone_output 1460;
# 发送文件优化
sendfile on;
sendfile_max_chunk 512k;
tcp_nopush on;
tcp_nodelay on;
# 超时设置
keepalive_timeout 65;
keepalive_requests 100;
client_body_timeout 12;
client_header_timeout 12;
send_timeout 10;
}
关键参数解析:
sendfile on:使用内核级别的零拷贝技术,提升文件传输效率tcp_nopush与tcp_nodelay:配合使用,优化 TCP 传输keepalive_requests:单个连接最大请求数,减少连接开销
3. Gzip 压缩优化
启用 Gzip 压缩,显著减少传输数据量。
http {
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_min_length 1000;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/xml+rss
application/rss+xml
font/truetype
font/opentype
application/vnd.ms-fontobject
image/svg+xml;
gzip_disable "msie6";
# Brotli 压缩(需要编译支持)
# brotli on;
# brotli_comp_level 6;
# brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
}
压缩策略:
- 压缩级别 6:平衡压缩比与 CPU 消耗
- 最小长度 1000:避免小文件压缩开销
- 包含字体和 SVG:现代 Web 应用常见资源
缓存策略优化
1. 浏览器缓存配置
通过 HTTP 缓存头控制浏览器缓存行为。
server {
listen 80;
server_name example.com;
root /var/www/html;
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# HTML 文件短期缓存或禁用缓存
location ~* \.(html|htm)$ {
expires 1h;
add_header Cache-Control "public, must-revalidate";
}
# API 接口禁用缓存
location /api/ {
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
add_header Expires "0";
}
}
2. 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;
# 缓存键设置
proxy_cache_key "$scheme$request_method$host$request_uri";
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
# 缓存配置
proxy_cache my_cache;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_valid any 5m;
# 缓存状态头(调试用)
add_header X-Cache-Status $upstream_cache_status;
# 缓存控制
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_background_update on;
proxy_cache_revalidate on;
proxy_cache_lock on;
# 代理头
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_set_header X-Forwarded-Proto $scheme;
}
# 缓存清理接口(需要 ngx_cache_purge 模块)
# 安装方法:https://github.com/nginx-modules/ngx_cache_purge
location ~ /purge(/.*) {
allow 127.0.0.1;
allow 192.168.1.0/24;
deny all;
proxy_cache_purge my_cache $scheme$request_method$host$1;
}
}
}
缓存策略要点:
keys_zone:定义缓存内存区域,10m 可存储约 8 万键max_size:磁盘缓存最大容量inactive:未访问缓存过期时间proxy_cache_use_stale:后端故障时使用过期缓存
3. FastCGI 缓存
PHP 等动态内容缓存配置。
http {
# FastCGI 缓存路径必须在 http 块中定义(不能在 server 块)
fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=fcgi_cache:10m max_size=10g
inactive=60m;
server {
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
# FastCGI 缓存
fastcgi_cache fcgi_cache;
fastcgi_cache_valid 200 60m;
fastcgi_cache_bypass $http_pragma $http_authorization;
fastcgi_no_cache $http_pragma $http_authorization;
# 缓存键包含用户标识(如需要个性化)
fastcgi_cache_key "$scheme$request_method$host$request_uri$cookie_user";
add_header X-FastCGI-Cache $upstream_cache_status;
}
}
}
注意:
fastcgi_cache_path必须在http块中定义,不能在server块中- 确保缓存目录存在且有写权限:
mkdir -p /var/cache/nginx/fastcgi && chown nginx:nginx /var/cache/nginx/fastcgi
连接与并发优化
1. 连接池优化
http {
# 上游连接池
upstream backend {
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
# 连接保持
keepalive 32;
keepalive_requests 100;
keepalive_timeout 60s;
}
server {
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
# 连接复用
proxy_connect_timeout 5s;
proxy_send_timeout 10s;
proxy_read_timeout 10s;
}
}
}
2. 限流与防刷
http {
# 限流区域定义
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=general_limit:10m rate=50r/s;
# 连接数限制
limit_conn_zone $binary_remote_addr zone=addr_limit:10m;
server {
# API 接口限流
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
limit_conn addr_limit 10;
limit_req_status 429;
limit_conn_status 429;
proxy_pass http://backend;
}
# 通用限流
location / {
limit_req zone=general_limit burst=50 nodelay;
limit_conn addr_limit 20;
}
}
}
限流策略说明:
rate=10r/s:平均每秒 10 个请求burst=20:允许突发 20 个请求nodelay:立即处理突发请求,不排队
HTTP/2 与 HTTP/3 部署
1. HTTP/2 配置
server {
listen 443 ssl http2;
server_name example.com;
# SSL/TLS 配置
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# 现代 TLS 配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/ssl/chain.crt;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# HSTS
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
# HTTP/2 推送(如需要)
# http2_push /style.css;
# http2_push /app.js;
}
2. HTTP/3 (QUIC) 配置
Nginx 1.25.0+ 支持 HTTP/3,需要编译时启用。
server {
# HTTP/3 监听(UDP 443)
listen 443 http3 reuseport;
# HTTP/2 和 HTTP/1.1 回退(TCP 443)
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# HTTP/3 需要 TLS 1.3
ssl_protocols TLSv1.3;
# Alt-Svc 头(告知客户端支持 HTTP/3)
# 注意:HTTP/3 使用 UDP,需要确保防火墙允许 UDP 443
add_header Alt-Svc 'h3=":443"; ma=86400' always;
# 其他配置...
location / {
root /var/www/html;
}
}
编译 Nginx 支持 HTTP/3:
选项 1:使用 BoringSSL(推荐用于 HTTP/3)
# 下载 BoringSSL
git clone https://github.com/google/boringssl.git
cd boringssl
mkdir build && cd build
cmake .. && make
# 编译 Nginx
./configure \
--with-http_v3_module \
--with-http_ssl_module \
--with-openssl=../boringssl \
--with-cc-opt="-I../boringssl/include" \
--with-ld-opt="-L../boringssl/build/ssl -L../boringssl/build/crypto"
make && sudo make install
选项 2:使用 OpenSSL 3.x(更常见)
# 使用系统 OpenSSL 3.x(需要 OpenSSL 1.1.1+)
./configure \
--with-http_v3_module \
--with-http_ssl_module
make && sudo make install
注意:
- HTTP/3 需要 Nginx 1.25.0+ 版本
- BoringSSL 提供更好的 HTTP/3 支持,但 OpenSSL 3.x 也可用
- 确保防火墙允许 UDP 443 端口(QUIC 使用 UDP)
- 编译前确保已安装必要的开发库:
apt-get install build-essential libpcre3-dev zlib1g-dev(Debian/Ubuntu)
安全优化实践
1. 安全响应头
server {
# 隐藏 Nginx 版本
server_tokens off;
# 安全响应头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
}
2. 请求过滤与防护
http {
# 禁用危险方法
if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE|OPTIONS)$ ) {
return 405;
}
# 阻止常见攻击模式
location ~* \.(php|jsp|cgi|asp|aspx)$ {
deny all;
return 403;
}
# SQL 注入和 XSS 防护(基础)
set $block 0;
if ($query_string ~* "union.*select.*\(|union.*all.*select.*\(|concat.*\(|\.\.\/|\.\.\\|exec.*\(|script.*<|javascript:|onerror=|onload=|<iframe") {
set $block 1;
}
if ($block = 1) {
return 403;
}
# 限制请求体大小
client_max_body_size 10m;
# 隐藏服务器信息(需要 headers-more-nginx-module 模块)
# 安装方法:https://github.com/openresty/headers-more-nginx-module
# more_set_headers -s 400,403,404,500,502,503,504 "Server: nginx";
# 或者使用标准方法隐藏版本(已在 server 块中配置 server_tokens off)
}
3. IP 白名单与黑名单
geo $blocked_ip {
default 0;
# 黑名单 IP
192.168.1.100 1;
10.0.0.50 1;
# 从文件读取
include /etc/nginx/blocked_ips.conf;
}
server {
if ($blocked_ip) {
return 403;
}
# 管理后台 IP 白名单
location /admin/ {
allow 192.168.1.0/24;
allow 10.0.0.0/8;
deny all;
proxy_pass http://backend;
}
}
负载均衡与高可用
1. 负载均衡策略
upstream backend {
# 轮询(默认)
# server 192.168.1.10:8080;
# server 192.168.1.11:8080;
# 权重轮询
server 192.168.1.10:8080 weight=3;
server 192.168.1.11:8080 weight=1;
# IP 哈希(会话保持)
# ip_hash;
# 最少连接
# least_conn;
# 一致性哈希(需要第三方模块)
# hash $request_uri consistent;
# 健康检查
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s backup;
# 连接保持
keepalive 32;
}
server {
location / {
proxy_pass http://backend;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
proxy_next_upstream_tries 3;
proxy_next_upstream_timeout 10s;
}
}
2. 主备与故障转移
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080 backup; # 备用服务器
server 192.168.1.12:8080 down; # 临时下线
}
# 使用 Nginx Plus 健康检查
upstream backend {
zone backend 64k;
least_conn;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
# 主动健康检查
health_check interval=5s fails=3 passes=2 uri=/health;
}
日志与监控优化
1. 日志格式优化
http {
# 自定义日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time"';
log_format json escape=json
'{'
'"time_local":"$time_local",'
'"remote_addr":"$remote_addr",'
'"remote_user":"$remote_user",'
'"request":"$request",'
'"status": $status,'
'"body_bytes_sent":$body_bytes_sent,'
'"request_time":$request_time,'
'"http_referrer":"$http_referer",'
'"http_user_agent":"$http_user_agent"'
'}';
access_log /var/log/nginx/access.log main buffer=32k flush=5s;
error_log /var/log/nginx/error.log warn;
# 按域名分离日志
server {
server_name example.com;
access_log /var/log/nginx/example.com.access.log main;
}
}
2. 性能监控配置
# 启用状态监控(需要 stub_status 模块)
server {
listen 127.0.0.1:8080;
server_name localhost;
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}
# 输出示例:
# Active connections: 291
# server accepts handled requests
# 16630948 16630948 31070465
# Reading: 6 Writing: 179 Waiting: 106
3. 实时日志分析
使用 GoAccess 或 ELK 进行日志分析:
# GoAccess 实时分析
goaccess /var/log/nginx/access.log --log-format=COMBINED --real-time-html --output=/var/www/report.html
# 或使用 tail + awk 简单统计
tail -f /var/log/nginx/access.log | awk '{print $9}' | sort | uniq -c | sort -rn
前沿技术应用
1. 动态模块加载
Nginx 1.9.11+ 支持动态模块,无需重新编译。
# 加载动态模块
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;
load_module modules/ngx_http_geoip2_module.so;
2. 流媒体与 WebSocket
# RTMP 流媒体(需要 nginx-rtmp-module)
rtmp {
server {
listen 1935;
application live {
live on;
record off;
hls on;
hls_path /var/www/hls;
hls_fragment 3s;
hls_playlist_length 60s;
}
}
}
# WebSocket 代理
server {
location /ws/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400;
}
}
3. 边缘计算与 CDN 集成
# 边缘缓存配置
http {
map $http_cf_visitor $is_bot {
default 0;
~*bot 1;
}
server {
# Cloudflare 或 CDN 集成
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
real_ip_header CF-Connecting-IP;
# 区分爬虫和真实用户
if ($is_bot) {
return 403;
}
}
}
4. 微服务与 API 网关
# API 网关配置
upstream user_service {
server 192.168.1.20:8001;
}
upstream order_service {
server 192.168.1.21:8002;
}
server {
location /api/users/ {
rewrite ^/api/users/(.*) /$1 break;
proxy_pass http://user_service;
}
location /api/orders/ {
rewrite ^/api/orders/(.*) /$1 break;
proxy_pass http://order_service;
}
# API 版本控制
location ~ ^/api/v(\d+)/(.*)$ {
set $version $1;
set $path $2;
rewrite ^ /v$version/$path break;
proxy_pass http://backend;
}
}
实战例与性能测试
例 1:高并发电商网站优化
场景: 日 PV 1000 万,峰值 QPS 5000
优化配置:
# nginx.conf
user nginx;
worker_processes auto;
worker_rlimit_nofile 100000;
events {
use epoll;
worker_connections 16384;
multi_accept on;
}
http {
# 基础优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 30;
keepalive_requests 1000;
# 压缩
gzip on;
gzip_vary on;
gzip_comp_level 6;
gzip_min_length 1000;
gzip_types text/plain text/css application/json application/javascript text/xml;
# 缓存
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=product_cache:100m
max_size=50g inactive=24h use_temp_path=off;
# 限流
limit_req_zone $binary_remote_addr zone=product_limit:10m rate=20r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
upstream backend {
least_conn;
server 10.0.1.10:8080 max_fails=3 fail_timeout=10s;
server 10.0.1.11:8080 max_fails=3 fail_timeout=10s;
keepalive 64;
}
server {
listen 80;
server_name shop.example.com;
# 静态资源
location ~* \.(jpg|jpeg|png|gif|css|js|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# 商品详情页缓存
location ~ ^/product/(\d+)$ {
limit_req zone=product_limit burst=30 nodelay;
proxy_pass http://backend;
proxy_cache product_cache;
proxy_cache_valid 200 10m;
proxy_cache_key "$scheme$request_method$host$request_uri";
add_header X-Cache-Status $upstream_cache_status;
}
# API 接口
location /api/ {
limit_req zone=product_limit burst=10 nodelay;
limit_conn conn_limit 5;
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
}
性能测试结果:
# 使用 wrk 压测
wrk -t12 -c400 -d30s --timeout 10s https://shop.example.com/product/12345
# 优化前:QPS 2000,平均响应时间 200ms
# 优化后:QPS 8000,平均响应时间 50ms
例 2:API 服务优化
场景: RESTful API,需要低延迟高并发
http {
# 连接池
upstream api_backend {
least_conn;
server 192.168.1.30:3000;
server 192.168.1.31:3000;
keepalive 100;
}
# API 限流
limit_req_zone $binary_remote_addr zone=api_rate:10m rate=100r/s;
limit_req_zone $binary_remote_addr zone=api_strict:10m rate=10r/s;
server {
listen 443 ssl http2;
server_name api.example.com;
# 禁用缓存
add_header Cache-Control "no-store, no-cache, must-revalidate";
location /api/v1/ {
# 限流
limit_req zone=api_rate burst=200 nodelay;
# CORS
add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
add_header Access-Control-Allow-Headers "Authorization, Content-Type" always;
if ($request_method = OPTIONS) {
return 204;
}
# 代理
proxy_pass http://api_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
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_connect_timeout 3s;
proxy_send_timeout 5s;
proxy_read_timeout 5s;
}
# 敏感接口更严格限流
location /api/v1/payment/ {
limit_req zone=api_strict burst=5 nodelay;
proxy_pass http://api_backend;
}
}
}
例 3:WordPress 多站点优化
# WordPress 优化配置
# 注意:fastcgi_cache_path 必须在 http 块中定义,不能在 server 块中
http {
# FastCGI 缓存路径(必须在 http 块)
fastcgi_cache_path /var/cache/nginx/wordpress levels=1:2
keys_zone=wp_cache:50m max_size=5g inactive=60m;
server {
listen 80;
server_name blog.example.com;
root /var/www/wordpress;
index index.php;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
# 缓存
fastcgi_cache wp_cache;
fastcgi_cache_valid 200 60m;
fastcgi_cache_bypass $http_pragma $http_authorization $cookie_comment_author;
fastcgi_no_cache $http_pragma $http_authorization $cookie_comment_author;
add_header X-FastCGI-Cache $upstream_cache_status;
}
# 静态资源
location ~* \.(jpg|jpeg|png|gif|css|js|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# 禁止访问敏感文件
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# WordPress 安全配置
location ~ /wp-admin {
# 限制访问频率
limit_req zone=general_limit burst=10 nodelay;
}
# 禁止执行 PHP 文件上传目录
location ~* /wp-content/uploads/.*\.php$ {
deny all;
}
}
}
系统级优化配置
1. 系统文件描述符限制
Nginx 需要足够的文件描述符来处理高并发连接。
# 编辑 /etc/security/limits.conf
# 添加以下内容
* soft nofile 65535
* hard nofile 65535
nginx soft nofile 65535
nginx hard nofile 65535
# 编辑 /etc/systemd/system/nginx.service.d/override.conf(如果使用 systemd)
[Service]
LimitNOFILE=65535
# 重新加载配置
systemctl daemon-reload
systemctl restart nginx
2. 内核参数优化(sysctl)
# 编辑 /etc/sysctl.conf,添加以下配置
# TCP 连接优化
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.ip_local_port_range = 1024 65535
# TCP 连接复用
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
# TCP 缓冲区
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# TCP 连接追踪
net.netfilter.nf_conntrack_max = 262144
# 应用配置
sysctl -p
3. 日志轮转配置
使用 logrotate 管理日志文件,避免日志文件过大。
# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 0640 nginx adm
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}
配置测试与验证
1. 配置文件测试
在应用配置前,务必先测试配置文件语法。
# 测试配置文件语法
nginx -t
# 测试配置文件并显示所有配置
nginx -T
# 测试配置文件并显示版本信息
nginx -V
# 如果测试通过,重新加载配置(不中断服务)
nginx -s reload
# 或者使用 systemd
systemctl reload nginx
2. 性能验证
# 检查 Nginx 状态
systemctl status nginx
# 查看 Nginx 进程
ps aux | grep nginx
# 查看连接数
netstat -an | grep :80 | wc -l
# 或使用 ss(更现代)
ss -ant | grep :80 | wc -l
# 查看 Nginx 统计信息(如果配置了 stub_status)
curl http://127.0.0.1:8080/nginx_status
3. 错误排查
# 查看错误日志
tail -f /var/log/nginx/error.log
# 查看访问日志
tail -f /var/log/nginx/access.log
# 检查配置文件包含的路径
nginx -T 2>&1 | grep -E "include|conf"
# 查看 Nginx 版本和编译信息
nginx -V
错误页面自定义
提供友好的错误页面,提升用户体验。
http {
# 自定义错误页面
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
server {
# 404 错误页面
location = /404.html {
root /var/www/html;
internal;
}
# 50x 错误页面
location = /50x.html {
root /var/www/html;
internal;
}
# 或者使用自定义错误页面并返回 JSON(API 服务)
location /api/ {
error_page 404 = @api_not_found;
error_page 500 502 503 504 = @api_error;
proxy_pass http://backend;
}
location @api_not_found {
default_type application/json;
return 404 '{"error":"Not Found","code":404}';
}
location @api_error {
default_type application/json;
return 500 '{"error":"Internal Server Error","code":500}';
}
}
}
SSL 证书自动续期
使用 Let's Encrypt 和 Certbot 实现证书自动续期。
# 安装 Certbot
apt-get install certbot python3-certbot-nginx # Debian/Ubuntu
yum install certbot python3-certbot-nginx # CentOS/RHEL
# 申请证书
certbot --nginx -d example.com -d www.example.com
# 测试自动续期
certbot renew --dry-run
# 设置自动续期(添加到 crontab)
crontab -e
# 添加以下行(每月检查并续期)
0 0 1 * * certbot renew --quiet --deploy-hook "systemctl reload nginx"
Nginx 配置示例(自动续期):
server {
listen 80;
server_name example.com www.example.com;
# Let's Encrypt 验证路径
location /.well-known/acme-challenge/ {
root /var/www/html;
}
# HTTP 重定向到 HTTPS
location / {
return 301 https://$server_name$request_uri;
}
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# SSL 证书(Certbot 会自动配置)
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# 其他配置...
}
性能测试与调优建议
1. 压力测试工具
# Apache Bench (ab)
ab -n 10000 -c 100 https://example.com/
# wrk(更现代)
wrk -t4 -c100 -d30s --timeout 10s https://example.com/
# 使用 Vegeta
echo "GET https://example.com/" | vegeta attack -duration=30s -rate=1000 | vegeta report
2. 性能监控指标
- QPS(每秒请求数):衡量吞吐量
- 响应时间:P50、P95、P99 延迟
- 错误率:4xx、5xx 错误比例
- 连接数:活跃连接和等待连接
- 缓存命中率:
$upstream_cache_status统计
3. 调优检查清单
基础配置:
- Worker 进程数 = CPU 核心数
- 文件描述符限制 ≥ 65535(系统级和 Nginx 配置)
- 启用 sendfile 和 tcp_nopush
- 配置合理的 keepalive 超时
- 配置系统内核参数(sysctl)
性能优化:
- 启用 Gzip/Brotli 压缩
- 配置静态资源缓存
- 设置代理缓存(如适用)
- 配置 FastCGI 缓存(如适用)
- 优化缓冲区大小
安全与限流:
- 配置限流防止过载
- 配置安全响应头
- 隐藏服务器版本信息
- 配置 IP 白名单/黑名单
- 设置 SSL/TLS 最佳实践
协议与模块:
- 启用 HTTP/2 或 HTTP/3
- 配置 OCSP Stapling
- 启用 HSTS
- 安装必要的第三方模块
监控与维护:
- 优化日志格式和轮转
- 配置日志轮转(logrotate)
- 设置性能监控(stub_status 或 Prometheus)
- 配置错误页面
- 设置 SSL 证书自动续期
- 定期进行性能测试
部署验证:
- 配置文件语法测试通过(nginx -t)
- 性能测试通过(QPS、延迟满足要求)
- 监控指标正常(错误率、缓存命中率等)
- 安全测试通过(SSL Labs、安全响应头检查)
常见问题与解决方案
1. 502 Bad Gateway
原因: 后端服务器无响应或连接超时
解决方案:
# 增加超时时间
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 检查后端服务状态
# 查看 FastCGI 进程
ps aux | grep php-fpm
# 检查 PHP-FPM 配置
systemctl status php8.1-fpm
2. 413 Request Entity Too Large
原因: 上传文件超过限制
解决方案:
# 增加客户端请求体大小限制
client_max_body_size 50m;
# 同时检查 PHP 配置
# php.ini: upload_max_filesize = 50M
# php.ini: post_max_size = 50M
3. 缓存不生效
排查步骤:
# 检查缓存目录权限
ls -la /var/cache/nginx/
chown -R nginx:nginx /var/cache/nginx/
# 检查缓存状态头
curl -I http://example.com/ | grep X-Cache-Status
# 查看缓存键
# 在配置中添加缓存调试
add_header X-Cache-Key "$scheme$request_method$host$request_uri";
4. 高并发下连接数不足
解决方案:
# 1. 检查系统限制
ulimit -n
# 2. 增加系统文件描述符限制(见系统级优化配置)
# 3. 调整 Nginx 配置
worker_rlimit_nofile 100000;
worker_connections 16384;
# 4. 优化内核参数
net.core.somaxconn = 65535
5. SSL 证书问题
# 检查证书有效期
openssl x509 -in /etc/nginx/ssl/cert.pem -noout -dates
# 测试 SSL 配置
openssl s_client -connect example.com:443 -servername example.com
# 在线测试工具
# https://www.ssllabs.com/ssltest/
总结
Nginx 优化是一个系统工程,需要根据实际业务场景进行针对性配置。关键优化点包括:
- 性能优化:Worker 进程、连接处理、缓冲区、压缩、系统级参数
- 缓存策略:浏览器缓存、代理缓存、FastCGI 缓存
- 安全加固:安全响应头、请求过滤、IP 限制、SSL/TLS 配置
- 负载均衡:多种算法选择、健康检查、故障转移
- 前沿技术:HTTP/2/3、动态模块、边缘计算
- 运维管理:配置测试、日志轮转、监控告警、证书管理
最佳实践建议:
- 配置前先测试:使用
nginx -t验证配置语法 - 渐进式优化:一次修改一个参数,观察效果后再继续
- 持续监控:建立监控体系,及时发现问题
- 定期审查:定期检查配置,清理无用规则
- 文档化:记录配置变更和优化效果
- 备份配置:修改前备份原配置,便于回滚
持续监控和调优是保持高性能的关键。建议定期进行压力测试,根据实际负载调整配置参数,并关注 Nginx 官方更新和新特性,以上这些已经够工作中常用且非常全面了。