http {
# 限制器配置:基于客户端IP限制请求速率
limit_req_zone $binary_remote_addr zone=healthcheck:10m rate=10r/s;
# $binary_remote_addr:使用客户端 IP 的二进制形式作为标识键
# zone=healthcheck:10m:创建名为healthcheck的共享内存区,大小 10MB(约存储 50 万 IP 状态)
# rate=10r/s:限制每个 IP 每秒最多 10 个请求(突发时可处理 10 个,超出则返回 503)
# 负载均衡组
upstream backend_servers {
least_conn;
ip_hash;
# 负载均衡策略:
# ip_hash:同一 IP 的请求始终路由到同一服务器(解决 session 会话保持)
# least_conn:优先将请求分配给当前连接数最少的服务器(适合长连接服务)
server backend1.example.com weight=3 max_fails=3 fail_timeout=30s slow_start=60s;
server backend2.example.com weight=2 max_fails=3 fail_timeout=30s slow_start=60s;
server backup.example.com backup;
#服务器参数:
# weight=3:权重值,影响被选中概率(backend1承担约 3/5 流量)
# max_fails=3:连续 3 次失败后标记为不可用
# fail_timeout=30s:不可用状态持续 30 秒
# slow_start=60s:故障恢复后 60 秒内逐渐增加负载(避免流量冲击)
# 健康检查
check interval=5000 rise=2 fall=3 timeout=1000 type=http;
check_http_send "GET /healthcheck HTTP/1.1\r\nHost: backend\r\nAuthorization: Basic dXNlcjpwYXNz\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
# 健康检查机制:
# interval=5000:每 5 秒检查一次
# rise=2:连续 2 次成功视为健康
# fall=3:连续 3 次失败视为不健康
# timeout=1000:检查请求超时时间 1 秒
# type=http:使用 HTTP 协议检查
# check_http_send:发送带 Basic 认证的 GET 请求(用户名:password = user:pass) 也可以不用认证
# check_http_expect_alive:仅 2xx/3xx 状态码视为健康
# 后端服务验证
# @app.route('/healthcheck')
# def healthcheck():
# auth = request.authorization
# if not auth or not check_auth(auth.username, auth.password):
# return "Unauthorized", 401
}
server {
listen 443 ssl;
server_name example.com;
# 安全头
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
add_header Content-Security-Policy "default-src 'self'";
# 安全响应头:
# X-Content-Type-Options: nosniff:防止浏览器 MIME 类型嗅探攻击
# X-Frame-Options: DENY:禁止页面被 iframe 嵌入
# Content-Security-Policy: default-src 'self':仅允许加载同源资源
location / {
proxy_pass http://backend_servers;
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_pass:转发请求到backend_servers负载均衡组
# proxy_set_header:
# Host $host:保留原始请求的域名
# X-Real-IP $remote_addr:传递客户端真实 IP
# X-Forwarded-For:追加代理服务器信息(格式:client, proxy1, proxy2)
# X-Forwarded-Proto:传递原始请求协议(http/https)
# 失败重试
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
proxy_next_upstream_tries 3;
# proxy_next_upstream:遇到指定错误时自动转发到下一台服务器
# proxy_next_upstream_tries:每个请求最多尝试 3 次
}
# 内部健康检查端点(仅允许内网访问)
location = /internal_health {
allow 10.0.0.0/8; # 允许10.0.0.0/8网段访问
deny all; # 拒绝其他所有访问
stub_status; # 输出Nginx状态信息
}
}
}http {
# 生成唯一请求 ID(用于分布式追踪)
load_module modules/ngx_http_uuid_module.so;
uuid_gen;
uuid_gen_format "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx";
# 功能:生成符合 RFC 4122 标准的 UUID v4,作为请求唯一标识
# 关键点:
# uuid_gen_format 中的 4 和 y 是 UUID v4 的固定格式要求
# $request_id 变量用于在后续配置中引用生成的 UUID
# 用途:分布式系统中追踪请求链路(如从 Nginx 到多个微服务)
# 高性能 JSON 日志格式(适合 ELK/Vector 等工具解析)
log_format json_prod escape=json '{
"ts": "$time_iso8601",
"ip": "$remote_addr",
"xff": "$http_x_forwarded_for",
"req_id": "$request_id",
"method": "$request_method",
"path": "$request_uri",
"proto": "$server_protocol",
"status": $status,
"size": $body_bytes_sent,
"rt": $request_time,
"upstream_rt": "$upstream_response_time",
"upstream_addr": "$upstream_addr",
"ua": "$http_user_agent",
"referer": "$http_referer"
}';
# "ts": "2023-10-15T14:30:45+08:00", // ISO 8601 时间戳
# "ip": "192.168.1.100", // 客户端 IP
# "xff": "103.21.244.0", // 真实客户端 IP(通过代理传递)
# "method": "GET", // HTTP 请求方法
# "req_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", // 请求唯一标识
# "path": "/api/users?page=1", // 请求路径
# "proto": "HTTP/1.1", // HTTP 协议版本
# "status": 200, // 响应状态码
# "size": 1234, // 响应体大小(字节)
# "rt": 0.235, // 请求总处理时间(秒)
# "upstream_rt": "0.210", // 上游服务器响应时间
# "upstream_addr": "10.0.0.1:8080", // 上游服务器地址
# "ua": "Mozilla/5.0 (Windows NT 10.0)", // 客户端 User-Agent
# "referer": "https://example.com/search" // 来源页面
# 简洁文本日志格式(适合快速排查问题)
log_format concise '[$time_local] $remote_addr $status '
'"$request_method $request_uri" '
'rt=$request_time uct="$upstream_connect_time" '
'urt="$upstream_response_time" req_id="$request_id"';
# [15/Oct/2023:14:30:45 +0800] 192.168.1.100 200 "GET /api/users?page=1" rt=0.235 uct="0.012" urt="0.210" req_id="f47ac10b-58cc-4372-a567-0e02b2c3d479"
server {
listen 443 ssl http2;
server_name example.com;
# 主日志:JSON 格式,用于长期存储和分析
access_log /var/log/nginx/access.json json_prod buffer=32k flush=5s;
# 性能优化:
# buffer=32k:32KB 缓冲区,减少磁盘 I/O 次数
# flush=5s:每 5 秒强制刷新一次,平衡实时性与性能
# 错误日志:包含更详细的错误信息
error_log /var/log/nginx/error.log notice;
# 静态资源路径:使用简洁日志减少磁盘 I/O
location ~* \.(js|css|png|jpg|gif|ico|woff|woff2|svg)$ {
access_log /var/log/nginx/static.log concise;
expires 7d;
}
# 使用简洁日志格式减少冗余信息
# 静态资源请求量大但业务价值低,单独存储便于分析
# expires 7d:浏览器缓存 7 天,减少重复请求
# 健康检查路径:关闭日志以减少噪声
location = /healthcheck {
access_log off;
return 200;
}
# 其他配置...
}
}