以下是 Nginx 常见场景的具体配置示例,配置文件可存放在 /etc/nginx/conf.d/
目录下(Linux)或直接修改 nginx.conf
(Windows):
一、基础配置:静态网站托管
配置文件(/etc/nginx/conf.d/mysite.conf
)
server {
listen 80;
server_name example.com www.example.com; # 替换为你的域名
# 网站根目录
root /var/www/html;
index index.html index.htm;
# 日志配置
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# 静态文件缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d; # 静态资源缓存30天
}
# 错误页面
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
}
操作步骤
- 创建网站目录:
sudo mkdir -p /var/www/html
- 添加测试文件:
echo "Hello, Nginx!" > /var/www/html/index.html
- 验证配置:
nginx -t
- 重载配置:
nginx -s reload
二、反向代理:转发到后端服务
场景1:代理到本地 Node.js 应用(端口3000)
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://localhost:3000; # 后端服务地址
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_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
场景2:代理到多个后端服务器(负载均衡)
# 定义后端服务器组
upstream backend_servers {
server backend1.example.com weight=5; # 权重5
server backend2.example.com weight=3; # 权重3
server backend3.example.com backup; # 备份服务器
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
# 其他 proxy_set_header 配置同上
}
}
三、HTTPS 配置(使用 Let's Encrypt 证书)
前提条件
- 已安装 Certbot:
sudo apt install certbot python3-certbot-nginx
- 域名已解析到服务器 IP
自动配置(推荐)
sudo certbot --nginx -d example.com -d www.example.com
Certbot 会自动修改 Nginx 配置并设置证书自动更新。
手动配置示例
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri; # 强制 HTTPS
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# 证书路径(Let's Encrypt 默认路径)
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# SSL 优化配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# 其他配置(如 root、location 等)同 HTTP 配置
}
四、URL 重写与跳转
示例1:www 到非 www 跳转
server {
listen 80;
server_name www.example.com;
return 301 https://example.com$request_uri;
}
示例2:路径重写
location /old-path/ {
rewrite ^/old-path/(.*)$ /new-path/$1 permanent; # 301 永久重定向
}
示例3:基于参数跳转
if ($args ~* "id=([0-9]+)") {
return 301 https://example.com/item/$1;
}
五、限流配置(防爬/防刷)
限制单个 IP 的请求频率
# http 块中定义限流规则
http {
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
server {
listen 80;
server_name example.com;
location /api/ {
limit_req zone=mylimit burst=20 nodelay;
# 每秒最多10个请求,突发最多20个,超出的请求直接返回503
}
}
}
六、WebSocket 代理支持
配置示例
server {
listen 80;
server_name ws.example.com;
location /ws/ {
proxy_pass http://backend_websocket_server;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
# 防止 WebSocket 连接超时
proxy_read_timeout 86400;
}
}
七、多站点配置(虚拟主机)
在同一服务器托管多个域名
# 站点1
server {
listen 80;
server_name site1.com www.site1.com;
root /var/www/site1;
}
# 站点2
server {
listen 80;
server_name site2.com www.site2.com;
root /var/www/site2;
}
八、静态文件优化配置
配置 Gzip 压缩
http {
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_buffers 16 8k;
gzip_http_version 1.1;
}
九、常见问题处理配置
1. 解决跨域请求(CORS)
location /api/ {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization' always;
# OPTIONS 请求直接返回 204
if ($request_method = 'OPTIONS') {
return 204;
}
}
2. 隐藏 Nginx 版本信息
http {
server_tokens off; # 隐藏响应头中的 Nginx 版本
}
配置验证与重载
每次修改配置后,务必执行:
nginx -t # 验证配置语法
nginx -s reload # 重载配置(不中断服务)
以上配置可根据实际需求组合使用,例如同时配置 HTTPS、反向代理和限流。如需更复杂的场景(如 A/B 测试、灰度发布),可进一步扩展配置。
以下是 Nginx 更高级的扩展配置示例,适用于复杂场景:
十、A/B 测试与灰度发布
基于 Cookie 的流量分发
http {
# 定义变量存储分流规则
map $cookie_ab_test $backend {
default backend_a;
"b" backend_b;
}
upstream backend_a {
server backend1.example.com;
}
upstream backend_b {
server backend2.example.com;
}
server {
listen 80;
server_name example.com;
# 首次访问设置 Cookie
if ($cookie_ab_test = "") {
set $ab_test $random % 2; # 随机分为两组
if ($ab_test = 0) {
add_header Set-Cookie "ab_test=a; path=/; domain=.example.com";
}
if ($ab_test = 1) {
add_header Set-Cookie "ab_test=b; path=/; domain=.example.com";
}
}
location / {
proxy_pass http://$backend;
}
}
}
十一、基于用户区域的流量路由
根据 IP 地理位置分发请求
# 需要安装 ngx_http_geoip2_module 模块
http {
geoip2 /path/to/GeoLite2-Country.mmdb {
$geoip2_data_country_code country iso_code;
}
map $geoip2_data_country_code $backend {
default backend_global;
"CN" backend_china;
"US" backend_usa;
}
upstream backend_global {
server global.example.com;
}
upstream backend_china {
server china.example.com;
}
upstream backend_usa {
server usa.example.com;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://$backend;
}
}
}
十二、内容缓存配置
配置代理缓存(如缓存 API 响应)
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 api.example.com;
location /static-api/ {
proxy_pass http://backend_api;
proxy_cache my_cache;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_valid 200 302 12h; # 成功响应缓存12小时
proxy_cache_valid 404 1m; # 404缓存1分钟
# 缓存命中时添加响应头,便于调试
add_header X-Cache $upstream_cache_status;
}
}
}
十三、健康检查与自动剔除故障节点
配置主动健康检查(需 nginx-plus 或 lua 模块)
http {
upstream backend_servers {
server backend1.example.com max_fails=3 fail_timeout=30s;
server backend2.example.com max_fails=3 fail_timeout=30s;
# 健康检查(Nginx Plus 功能)
zone backend 64k;
health_check interval=5s fails=3 passes=2 uri=/health;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
}
}
}
使用 Lua 模块实现健康检查(开源版)
# 需要安装 ngx_lua 模块
http {
lua_shared_dict healthcheck 1m;
init_by_lua_block {
local hc = require "resty.healthcheck"
local checker = hc.new({
name = "backend_checker",
shm_name = "healthcheck",
type = "http",
http_req = "GET /health HTTP/1.0\r\nHost: backend\r\n\r\n",
interval = 2000, # 2秒检查一次
timeout = 1000, # 超时时间1秒
fall = 3, # 连续3次失败标记为不可用
rise = 2, # 连续2次成功标记为可用
})
-- 添加后端服务器
checker:add_target("backend1.example.com", nil, 80, true)
checker:add_target("backend2.example.com", nil, 80, true)
-- 启动后台检查
local ok, err = checker:start()
if not ok then
ngx.log(ngx.ERR, "failed to start health checker: ", err)
return
end
}
upstream backend_servers {
server backend1.example.com;
server backend2.example.com;
# 使用 Lua 脚本判断服务器是否健康
server 0.0.0.1; # 防止 upstream 为空
balancer_by_lua_block {
local hc = require "resty.healthcheck"
local checker = hc.new({
name = "backend_checker",
shm_name = "healthcheck",
type = "http",
})
local ok, err = checker:get_reachable()
if not ok then
ngx.log(ngx.ERR, "no reachable backend server: ", err)
return ngx.exit(500)
end
-- 设置要代理的服务器
local host, port = ok.host, ok.port
local ok, err = ngx.balancer.set_current_peer(host, port)
if not ok then
ngx.log(ngx.ERR, "failed to set current peer: ", err)
return ngx.exit(500)
end
}
}
}
十四、请求限流与熔断
基于漏桶算法的限流
http {
# 定义漏桶限流规则
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=5r/s; # 每秒5个请求
server {
listen 80;
server_name api.example.com;
location /api/ {
limit_req zone=api_limit burst=10 nodelay; # 突发10个请求
# 超过限流时返回自定义错误页面
error_page 503 @api_blocked;
}
location @api_blocked {
default_type application/json;
return 503 '{"error":"Too many requests","code":429}';
}
}
}
熔断机制(当后端服务不可用时)
upstream backend_servers {
server backend1.example.com;
server backend2.example.com;
# 当后端服务器返回500、502、503、504时,将请求转发到其他服务器
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
}
十五、WebSocket 集群与会话保持
基于 IP Hash 的会话保持
upstream websocket_backend {
ip_hash; # 相同IP的请求始终转发到同一后端服务器
server backend1.example.com:8080;
server backend2.example.com:8080;
}
server {
listen 80;
server_name ws.example.com;
location /ws/ {
proxy_pass http://websocket_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 3600s;
}
}
十六、自定义日志格式与分析
JSON 格式日志
http {
log_format json_log '{
"timestamp": "$time_iso8601",
"remote_addr": "$remote_addr",
"host": "$host",
"request": "$request",
"status": $status,
"body_bytes_sent": $body_bytes_sent,
"request_time": $request_time,
"upstream_response_time": "$upstream_response_time",
"http_referer": "$http_referer",
"http_user_agent": "$http_user_agent"
}';
server {
listen 80;
server_name example.com;
access_log /var/log/nginx/access_json.log json_log;
}
}
十七、HTTP/2 与 TLS 优化配置
HTTP/2 与 OCSP 装订
server {
listen 443 ssl http2;
server_name example.com;
# 证书配置
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# 启用 OCSP 装订
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# TLS 优化
ssl_protocols TLSv1.3 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384";
# HTTP/2 优化
http2_push_preload on; # 启用 HTTP/2 预推送
}
十八、自定义错误页面
配置全局错误页面
http {
# 定义错误页面路径
error_page 400 /errors/400.html;
error_page 401 /errors/401.html;
error_page 403 /errors/403.html;
error_page 404 /errors/404.html;
error_page 500 502 503 504 /errors/50x.html;
server {
listen 80;
server_name example.com;
location /errors/ {
internal; # 只允许内部重定向访问
root /var/www/html;
}
}
}
十九、Nginx 与 Lua 脚本集成
示例:请求签名验证
# 需要安装 ngx_lua 模块
server {
listen 80;
server_name api.example.com;
location /api/ {
# 验证请求签名
access_by_lua_block {
local secret_key = "your_secret_key"
local request_time = ngx.var.arg_timestamp
local signature = ngx.var.arg_signature
# 检查时间戳是否过期(防止重放攻击)
local current_time = os.time()
if not request_time or math.abs(current_time - tonumber(request_time)) > 300 then
ngx.status = ngx.HTTP_UNAUTHORIZED
ngx.say('{"error":"Invalid timestamp"}')
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
# 验证签名
local args = ngx.req.get_uri_args()
local sorted_keys = {}
for k, _ in pairs(args) do
if k ~= "sign" then
table.insert(sorted_keys, k)
end
end
table.sort(sorted_keys)
local sign_str = ""
for _, k in ipairs(sorted_keys) do
sign_str = sign_str .. k .. "=" .. args[k] .. "&"
end
sign_str = sign_str .. "key=" .. secret_key
local resty_sha1 = require "resty.sha1"
local str = require "resty.string"
local sha1 = resty_sha1:new()
sha1:update(sign_str)
local digest = sha1:final()
local calculated_sign = str.to_hex(digest)
if calculated_sign ~= signature then
ngx.status = ngx.HTTP_UNAUTHORIZED
ngx.say('{"error":"Invalid signature"}')
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
}
proxy_pass http://backend_api;
}
}
二十、基于 JWT 的认证
JWT 验证示例
# 需要安装 lua-resty-jwt 模块
server {
listen 80;
server_name auth.example.com;
location /api/ {
access_by_lua_block {
local jwt = require "resty.jwt"
local secret = "your_jwt_secret"
-- 从请求头中获取 JWT
local auth_header = ngx.var.http_Authorization
if not auth_header then
ngx.status = ngx.HTTP_UNAUTHORIZED
ngx.say('{"error":"Authorization header missing"}')
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
-- 提取 token
local _, _, token = string.find(auth_header, "Bearer%s+(.+)")
if not token then
ngx.status = ngx.HTTP_UNAUTHORIZED
ngx.say('{"error":"Invalid token format"}')
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
-- 验证 JWT
local jwt_obj = jwt:verify(secret, token)
if not jwt_obj.verified then
ngx.status = ngx.HTTP_UNAUTHORIZED
ngx.say('{"error":"' .. jwt_obj.reason .. '"}')
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
-- 将用户信息传递给后端
ngx.req.set_header("X-User-ID", jwt_obj.payload.user_id)
ngx.req.set_header("X-User-Role", jwt_obj.payload.role)
}
proxy_pass http://backend_api;
}
}
配置验证与重载
每次修改配置后,务必执行:
nginx -t # 验证配置语法
nginx -s reload # 重载配置(不中断服务)
以上配置涵盖了复杂场景下的高级应用,可根据实际需求组合使用。对于生产环境,建议先在测试环境验证配置,确保稳定性。
评论 (0)