# main 块(全局配置)
worker_processes auto; # 自动匹配 CPU 核心数
worker_rlimit_nofile 51200; # 设置 worker 进程最大 FD 数
# 错误日志
error_log /var/log/nginx/error.log notice;
error_log /dev/stdout notice; # 将错误日志输出到标准输出,方便 Docker 容器日志管理
# events 块
events {
worker_connections 5120; # 单个 worker 最大并发连接
use epoll; # 高性能事件模型(Linux 推荐)
multi_accept on; # 一次性接受所有新连接
}
http {
include mime.types;
default_type application/octet-stream;
server_tokens off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 60;
keepalive_requests 1000;
types_hash_max_size 4096;
server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
client_max_body_size 1024m;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /dev/stdout main; # 将访问日志输出到标准输出,方便 Docker 容器日志管理
gzip on;
gzip_min_length 10k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 6;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_disable "MSIE [1-6]\.";
# 1. 创建限流共享内存区域(仅http块)
limit_req_zone $binary_remote_addr zone=api:10m rate=100r/s; # 频率限流:单IP 100请求/秒
limit_conn_zone $binary_remote_addr zone=perip:10m; # 按IP限流区域
limit_conn_zone $server_name zone=perserver:10m; # 按域名限流区域
# 2. 全局限流默认值(可在server/location覆盖)
limit_req_log_level warn; # 频率限流触发时记录 warn 日志
limit_req_status 429; # 频率限流返回 429(请求过多),而非默认 503
limit_conn_log_level warn; # 并发限流触发时记录 warn 日志
limit_conn_status 503; # 并发限流返回503错误(默认503)
include /etc/nginx/conf/conf.d/*.conf;
}
# 上游服务
upstream gateway {
least_conn;
server 10.0.1.10:8080 weight=1 max_fails=3 fail_timeout=30s;
server 10.0.1.11:8080 weight=1 max_fails=3 fail_timeout=30s backup;
keepalive 100;
}
# 前端站点
server {
listen 80;
listen 443 ssl http2;
server_name www.example.com example.com;
access_log /www/sites/www.example.com/log/access.log main;
error_log /www/sites/www.example.com/log/error.log notice;
location ~ ^/(\.user.ini|\.htaccess|\.git|\.env|\.svn|\.project|LICENSE|README.md) {
return 404;
}
# 3. 生效限流规则
limit_conn perip 100; # 单个IP最多100个并发连接
limit_conn perserver 1000; # 该域名总并发最多1000个连接
limit_req zone=api burst=100 nodelay; # 频率限流:基础速率 + 突发缓冲 + 无延迟
if ($scheme = http) {
return 301 https://$host$request_uri;
}
ssl_certificate /www/sites/www.example.com/ssl/fullchain.pem;
ssl_certificate_key /www/sites/www.example.com/ssl/privkey.pem;
ssl_protocols TLSv1.3 TLSv1.2;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:!aNULL:!eNULL:!EXPORT:!DSS:!DES:!RC4:!3DES:!MD5:!PSK:!KRB5:!SRP:!CAMELLIA:!SEED;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
error_page 497 https://$host$request_uri;
proxy_set_header X-Forwarded-Proto https;
# 安全头
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=31536000";
root /www/sites/www.example.com/index;
index index.html;
# 静态资源
location ~* .*\.(js|css|png|jpg|jpeg|gif|webp|webm|avif|ico|bmp|swf|eot|svg|ttf|woff2?)$ {
expires 30d;
access_log off;
log_not_found off;
add_header Cache-Control "public, immutable";
}
# SPA路由
location / {
try_files $uri $uri/ /index.html;
}
# 配置 stub_status 访问路径(推荐设置访问限制,提高安全性)
location /nginx_status {
# 启用统计信息功能
stub_status on;
# 关闭日志记录(避免统计请求占用日志空间)
access_log off;
# 允许指定 IP 访问(安全加固,拒绝所有 IP 后放行信任 IP)
allow 127.0.0.1; # 允许本地访问
allow 192.168.1.0/24; # 允许内网网段访问(根据你的实际网段调整)
deny all; # 拒绝其他所有 IP 访问
}
# API代理
location ^~ /api/ {
proxy_pass http://gateway/;
proxy_http_version 1.1;
# 核心请求头透传(后端识别真实客户端信息)
proxy_set_header Host $host; # 透传客户端请求的 Host 头
proxy_set_header X-Real-IP $remote_addr; # 透传客户端真实 IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 透传代理链 IP(含多层代理)
proxy_set_header X-Forwarded-Proto $scheme; # 透传协议(http/https)
proxy_set_header X-Forwarded-Port $server_port; # 透传客户端访问的端口
proxy_set_header Connection ""; # 清空 Connection 头,避免后端关闭长连接
# 响应头配置
add_header X-Cache $upstream_cache_status; # 标识后端缓存状态(HIT/MISS/EXPIRED)
add_header Cache-Control no-cache; # 禁用客户端缓存 API 响应
# 代理超时配置(配合 fail_timeout)
proxy_connect_timeout 5s; # 连接后端超时(短一点,快速检测故障)
proxy_read_timeout 60s; # 读取后端响应超时
proxy_send_timeout 60s;
}
}
# API站点(如果需要独立域名)
server {
listen 80;
listen 443 ssl http2;
server_name api.example.com;
access_log /www/sites/api.example.com/log/access.log main;
error_log /www/sites/api.example.com/log/error.log notice;
limit_conn perip 10;
limit_conn perserver 1000;
limit_req zone=api burst=100 nodelay;
if ($scheme = http) {
return 301 https://$host$request_uri;
}
ssl_certificate /www/sites/api.example.com/ssl/fullchain.pem;
ssl_certificate_key /www/sites/api.example.com/ssl/privkey.pem;
ssl_protocols TLSv1.3 TLSv1.2;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:!aNULL:!eNULL:!EXPORT:!DSS:!DES:!RC4:!3DES:!MD5:!PSK:!KRB5:!SRP:!CAMELLIA:!SEED;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
error_page 497 https://$host$request_uri;
proxy_set_header X-Forwarded-Proto https;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=31536000";
location ^~ / {
proxy_pass http://gateway/;
proxy_http_version 1.1;
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;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header Connection "";
add_header X-Cache $upstream_cache_status;
add_header Cache-Control no-cache;
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
}