前言
💡 痛点:网站访问慢?单点故障?HTTPS 配置复杂?缓存策略不会配?
🎯 解决方案 :Nginx 高级配置实战,从负载均衡 到SSL 优化 ,从缓存策略 到性能调优,手把手教你打造高性能 Web 服务。
为什么要深入 Nginx?
#mermaid-svg-9YcbKA5kWqHXdX5m{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-9YcbKA5kWqHXdX5m .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-9YcbKA5kWqHXdX5m .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-9YcbKA5kWqHXdX5m .error-icon{fill:#552222;}#mermaid-svg-9YcbKA5kWqHXdX5m .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-9YcbKA5kWqHXdX5m .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-9YcbKA5kWqHXdX5m .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-9YcbKA5kWqHXdX5m .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-9YcbKA5kWqHXdX5m .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-9YcbKA5kWqHXdX5m .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-9YcbKA5kWqHXdX5m .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-9YcbKA5kWqHXdX5m .marker{fill:#333333;stroke:#333333;}#mermaid-svg-9YcbKA5kWqHXdX5m .marker.cross{stroke:#333333;}#mermaid-svg-9YcbKA5kWqHXdX5m svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-9YcbKA5kWqHXdX5m p{margin:0;}#mermaid-svg-9YcbKA5kWqHXdX5m .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-9YcbKA5kWqHXdX5m .cluster-label text{fill:#333;}#mermaid-svg-9YcbKA5kWqHXdX5m .cluster-label span{color:#333;}#mermaid-svg-9YcbKA5kWqHXdX5m .cluster-label span p{background-color:transparent;}#mermaid-svg-9YcbKA5kWqHXdX5m .label text,#mermaid-svg-9YcbKA5kWqHXdX5m span{fill:#333;color:#333;}#mermaid-svg-9YcbKA5kWqHXdX5m .node rect,#mermaid-svg-9YcbKA5kWqHXdX5m .node circle,#mermaid-svg-9YcbKA5kWqHXdX5m .node ellipse,#mermaid-svg-9YcbKA5kWqHXdX5m .node polygon,#mermaid-svg-9YcbKA5kWqHXdX5m .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-9YcbKA5kWqHXdX5m .rough-node .label text,#mermaid-svg-9YcbKA5kWqHXdX5m .node .label text,#mermaid-svg-9YcbKA5kWqHXdX5m .image-shape .label,#mermaid-svg-9YcbKA5kWqHXdX5m .icon-shape .label{text-anchor:middle;}#mermaid-svg-9YcbKA5kWqHXdX5m .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-9YcbKA5kWqHXdX5m .rough-node .label,#mermaid-svg-9YcbKA5kWqHXdX5m .node .label,#mermaid-svg-9YcbKA5kWqHXdX5m .image-shape .label,#mermaid-svg-9YcbKA5kWqHXdX5m .icon-shape .label{text-align:center;}#mermaid-svg-9YcbKA5kWqHXdX5m .node.clickable{cursor:pointer;}#mermaid-svg-9YcbKA5kWqHXdX5m .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-9YcbKA5kWqHXdX5m .arrowheadPath{fill:#333333;}#mermaid-svg-9YcbKA5kWqHXdX5m .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-9YcbKA5kWqHXdX5m .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-9YcbKA5kWqHXdX5m .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-9YcbKA5kWqHXdX5m .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-9YcbKA5kWqHXdX5m .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-9YcbKA5kWqHXdX5m .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-9YcbKA5kWqHXdX5m .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-9YcbKA5kWqHXdX5m .cluster text{fill:#333;}#mermaid-svg-9YcbKA5kWqHXdX5m .cluster span{color:#333;}#mermaid-svg-9YcbKA5kWqHXdX5m div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-9YcbKA5kWqHXdX5m .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-9YcbKA5kWqHXdX5m rect.text{fill:none;stroke-width:0;}#mermaid-svg-9YcbKA5kWqHXdX5m .icon-shape,#mermaid-svg-9YcbKA5kWqHXdX5m .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-9YcbKA5kWqHXdX5m .icon-shape p,#mermaid-svg-9YcbKA5kWqHXdX5m .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-9YcbKA5kWqHXdX5m .icon-shape .label rect,#mermaid-svg-9YcbKA5kWqHXdX5m .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-9YcbKA5kWqHXdX5m .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-9YcbKA5kWqHXdX5m .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-9YcbKA5kWqHXdX5m :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 🌐 为什么学 Nginx?
实际场景
Nginx 优势
🚀 高并发网站
🔒 HTTPS 加速
⚡ 静态资源加速
🔄 反向代理/负载均衡
✅ 高性能(单机 10 万+ 并发)
✅ 低资源消耗
✅ 配置简单灵活
✅ 生态丰富
本文目标: 掌握 Nginx 高级配置,打造生产级 Web 服务。
一、Nginx 架构与核心概念
1.1 Nginx 架构解析
#mermaid-svg-lSXXXfhjHSv423EF{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-lSXXXfhjHSv423EF .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-lSXXXfhjHSv423EF .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-lSXXXfhjHSv423EF .error-icon{fill:#552222;}#mermaid-svg-lSXXXfhjHSv423EF .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-lSXXXfhjHSv423EF .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-lSXXXfhjHSv423EF .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-lSXXXfhjHSv423EF .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-lSXXXfhjHSv423EF .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-lSXXXfhjHSv423EF .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-lSXXXfhjHSv423EF .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-lSXXXfhjHSv423EF .marker{fill:#333333;stroke:#333333;}#mermaid-svg-lSXXXfhjHSv423EF .marker.cross{stroke:#333333;}#mermaid-svg-lSXXXfhjHSv423EF svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-lSXXXfhjHSv423EF p{margin:0;}#mermaid-svg-lSXXXfhjHSv423EF .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-lSXXXfhjHSv423EF .cluster-label text{fill:#333;}#mermaid-svg-lSXXXfhjHSv423EF .cluster-label span{color:#333;}#mermaid-svg-lSXXXfhjHSv423EF .cluster-label span p{background-color:transparent;}#mermaid-svg-lSXXXfhjHSv423EF .label text,#mermaid-svg-lSXXXfhjHSv423EF span{fill:#333;color:#333;}#mermaid-svg-lSXXXfhjHSv423EF .node rect,#mermaid-svg-lSXXXfhjHSv423EF .node circle,#mermaid-svg-lSXXXfhjHSv423EF .node ellipse,#mermaid-svg-lSXXXfhjHSv423EF .node polygon,#mermaid-svg-lSXXXfhjHSv423EF .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-lSXXXfhjHSv423EF .rough-node .label text,#mermaid-svg-lSXXXfhjHSv423EF .node .label text,#mermaid-svg-lSXXXfhjHSv423EF .image-shape .label,#mermaid-svg-lSXXXfhjHSv423EF .icon-shape .label{text-anchor:middle;}#mermaid-svg-lSXXXfhjHSv423EF .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-lSXXXfhjHSv423EF .rough-node .label,#mermaid-svg-lSXXXfhjHSv423EF .node .label,#mermaid-svg-lSXXXfhjHSv423EF .image-shape .label,#mermaid-svg-lSXXXfhjHSv423EF .icon-shape .label{text-align:center;}#mermaid-svg-lSXXXfhjHSv423EF .node.clickable{cursor:pointer;}#mermaid-svg-lSXXXfhjHSv423EF .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-lSXXXfhjHSv423EF .arrowheadPath{fill:#333333;}#mermaid-svg-lSXXXfhjHSv423EF .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-lSXXXfhjHSv423EF .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-lSXXXfhjHSv423EF .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-lSXXXfhjHSv423EF .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-lSXXXfhjHSv423EF .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-lSXXXfhjHSv423EF .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-lSXXXfhjHSv423EF .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-lSXXXfhjHSv423EF .cluster text{fill:#333;}#mermaid-svg-lSXXXfhjHSv423EF .cluster span{color:#333;}#mermaid-svg-lSXXXfhjHSv423EF div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-lSXXXfhjHSv423EF .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-lSXXXfhjHSv423EF rect.text{fill:none;stroke-width:0;}#mermaid-svg-lSXXXfhjHSv423EF .icon-shape,#mermaid-svg-lSXXXfhjHSv423EF .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-lSXXXfhjHSv423EF .icon-shape p,#mermaid-svg-lSXXXfhjHSv423EF .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-lSXXXfhjHSv423EF .icon-shape .label rect,#mermaid-svg-lSXXXfhjHSv423EF .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-lSXXXfhjHSv423EF .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-lSXXXfhjHSv423EF .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-lSXXXfhjHSv423EF :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 客户端请求
Master 进程
Worker 进程 1
Worker 进程 2
Worker 进程 N
事件驱动
上游服务器 1
上游服务器 2
静态文件
核心特点:
| 特点 | 说明 | 优势 |
|---|---|---|
| 事件驱动 | 异步非阻塞 | 高并发、低资源 |
| 多进程 | Master + 多个 Worker | 稳定、易扩展 |
| 模块化 | 核心 + 扩展模块 | 灵活、功能丰富 |
| 热部署 | 平滑升级 | 零停机 |
1.2 配置文件结构
nginx
# ===== Nginx 配置文件结构 =====
# 主配置文件:/etc/nginx/nginx.conf(Linux)
# 或 C:\nginx\conf\nginx.conf(Windows)
# ----- 1. 全局块 -----
user nginx; # 运行用户
worker_processes auto; # Worker 进程数(auto = CPU 核心数)
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
# ----- 2. Events 块 -----
events {
worker_connections 1024; # 每个 Worker 最大连接数
use epoll; # 使用 epoll 模型(Linux)
multi_accept on; # 一次接受多个连接
}
# ----- 3. HTTP 块 -----
http {
# 3.1 基础配置
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 3.2 日志格式
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 /var/log/nginx/access.log main;
# 3.3 性能优化
sendfile on; # 零拷贝
tcp_nopush on; # 优化网络传输
tcp_nodelay on; # 禁用 Nagle 算法
keepalive_timeout 65; # 长连接超时
# 3.4 Gzip 压缩
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;
# 3.5 引入其他配置
include /etc/nginx/conf.d/*.conf;
# ----- 4. Server 块(虚拟主机)-----
server {
listen 80;
server_name example.com;
# 4.1 Location 块
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /api {
proxy_pass http://backend;
}
}
# ----- 5. Upstream 块(负载均衡)-----
upstream backend {
server backend1.example.com:8080;
server backend2.example.com:8080;
}
}
二、负载均衡实战
2.1 负载均衡策略
#mermaid-svg-7ineQKEU2Ga0Ssea{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-7ineQKEU2Ga0Ssea .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-7ineQKEU2Ga0Ssea .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-7ineQKEU2Ga0Ssea .error-icon{fill:#552222;}#mermaid-svg-7ineQKEU2Ga0Ssea .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-7ineQKEU2Ga0Ssea .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-7ineQKEU2Ga0Ssea .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-7ineQKEU2Ga0Ssea .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-7ineQKEU2Ga0Ssea .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-7ineQKEU2Ga0Ssea .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-7ineQKEU2Ga0Ssea .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-7ineQKEU2Ga0Ssea .marker{fill:#333333;stroke:#333333;}#mermaid-svg-7ineQKEU2Ga0Ssea .marker.cross{stroke:#333333;}#mermaid-svg-7ineQKEU2Ga0Ssea svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-7ineQKEU2Ga0Ssea p{margin:0;}#mermaid-svg-7ineQKEU2Ga0Ssea .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-7ineQKEU2Ga0Ssea .cluster-label text{fill:#333;}#mermaid-svg-7ineQKEU2Ga0Ssea .cluster-label span{color:#333;}#mermaid-svg-7ineQKEU2Ga0Ssea .cluster-label span p{background-color:transparent;}#mermaid-svg-7ineQKEU2Ga0Ssea .label text,#mermaid-svg-7ineQKEU2Ga0Ssea span{fill:#333;color:#333;}#mermaid-svg-7ineQKEU2Ga0Ssea .node rect,#mermaid-svg-7ineQKEU2Ga0Ssea .node circle,#mermaid-svg-7ineQKEU2Ga0Ssea .node ellipse,#mermaid-svg-7ineQKEU2Ga0Ssea .node polygon,#mermaid-svg-7ineQKEU2Ga0Ssea .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-7ineQKEU2Ga0Ssea .rough-node .label text,#mermaid-svg-7ineQKEU2Ga0Ssea .node .label text,#mermaid-svg-7ineQKEU2Ga0Ssea .image-shape .label,#mermaid-svg-7ineQKEU2Ga0Ssea .icon-shape .label{text-anchor:middle;}#mermaid-svg-7ineQKEU2Ga0Ssea .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-7ineQKEU2Ga0Ssea .rough-node .label,#mermaid-svg-7ineQKEU2Ga0Ssea .node .label,#mermaid-svg-7ineQKEU2Ga0Ssea .image-shape .label,#mermaid-svg-7ineQKEU2Ga0Ssea .icon-shape .label{text-align:center;}#mermaid-svg-7ineQKEU2Ga0Ssea .node.clickable{cursor:pointer;}#mermaid-svg-7ineQKEU2Ga0Ssea .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-7ineQKEU2Ga0Ssea .arrowheadPath{fill:#333333;}#mermaid-svg-7ineQKEU2Ga0Ssea .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-7ineQKEU2Ga0Ssea .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-7ineQKEU2Ga0Ssea .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-7ineQKEU2Ga0Ssea .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-7ineQKEU2Ga0Ssea .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-7ineQKEU2Ga0Ssea .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-7ineQKEU2Ga0Ssea .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-7ineQKEU2Ga0Ssea .cluster text{fill:#333;}#mermaid-svg-7ineQKEU2Ga0Ssea .cluster span{color:#333;}#mermaid-svg-7ineQKEU2Ga0Ssea div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-7ineQKEU2Ga0Ssea .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-7ineQKEU2Ga0Ssea rect.text{fill:none;stroke-width:0;}#mermaid-svg-7ineQKEU2Ga0Ssea .icon-shape,#mermaid-svg-7ineQKEU2Ga0Ssea .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-7ineQKEU2Ga0Ssea .icon-shape p,#mermaid-svg-7ineQKEU2Ga0Ssea .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-7ineQKEU2Ga0Ssea .icon-shape .label rect,#mermaid-svg-7ineQKEU2Ga0Ssea .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-7ineQKEU2Ga0Ssea .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-7ineQKEU2Ga0Ssea .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-7ineQKEU2Ga0Ssea :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 负载均衡策略
轮询
Round Robin
加权轮询
Weighted
IP 哈希
IP Hash
最少连接
Least Conn
URL 哈希
URL Hash
✅ 默认策略
❌ 不考虑服务器性能
✅ 根据性能分配
✅ 生产推荐
✅ 会话保持
❌ 可能不均匀
2.2 负载均衡配置
nginx
# ===== 负载均衡配置 =====
# 文件:/etc/nginx/conf.d/load-balancer.conf
# ----- 1. 定义上游服务器组 -----
upstream backend {
# 策略 1:轮询(默认)
server 192.168.1.101:8080;
server 192.168.1.102:8080;
server 192.168.1.103:8080;
}
upstream backend_weighted {
# 策略 2:加权轮询(推荐)
server 192.168.1.101:8080 weight=3; # 性能好的服务器权重高
server 192.168.1.102:8080 weight=2;
server 192.168.1.103:8080 weight=1;
}
upstream backend_ip_hash {
# 策略 3:IP 哈希(会话保持)
ip_hash;
server 192.168.1.101:8080;
server 192.168.1.102:8080;
server 192.168.1.103:8080;
}
upstream backend_least_conn {
# 策略 4:最少连接
least_conn;
server 192.168.1.101:8080;
server 192.168.1.102:8080;
server 192.168.1.103:8080;
}
# ----- 2. 健康检查 -----
upstream backend_health {
# Nginx Plus 或 Nginx 商业版支持主动健康检查
# 开源版使用 max_fails + fail_timeout 实现被动健康检查
server 192.168.1.101:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.102:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.103:8080 backup; # 备份服务器
server 192.168.1.104:8080 down; # 标记不可用
}
# ----- 3. 负载均衡器配置 -----
server {
listen 80;
server_name lb.example.com;
# 访问日志
access_log /var/log/nginx/load-balancer.log main;
location / {
# 反向代理到上游服务器组
proxy_pass http://backend_weighted;
# ===== 代理配置(重要)=====
# 传递客户端真实 IP
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 Host $host;
# 超时配置
proxy_connect_timeout 5s; # 连接上游服务器超时
proxy_send_timeout 60s; # 发送请求超时
proxy_read_timeout 60s; # 读取响应超时
# 禁用缓存(实时应用)
proxy_buffering off;
# 错误重试
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
proxy_next_upstream_tries 3;
proxy_next_upstream_timeout 10s;
}
# 健康检查端点(手动)
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
# 状态监控(需要 stub_status 模块)
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1; # 只允许本地访问
deny all;
}
}
2.3 会话保持配置
nginx
# ===== 会话保持(Session Persistence)=====
# 方式 1:IP Hash(上面已介绍)
upstream backend_session {
ip_hash;
server 192.168.1.101:8080;
server 192.168.1.102:8080;
}
# 方式 2:Cookie 插入(需要 Nginx Plus 或第三方模块)
# 开源版可以使用 nginx-sticky-module
# 方式 3:根据请求参数(自定义)
map $cookie_session_id $backend_server {
default "192.168.1.101:8080";
"~*server2" "192.168.1.102:8080";
"~*server3" "192.168.1.103:8080";
}
server {
location / {
proxy_pass http://$backend_server;
}
}
三、SSL/TLS 优化配置
3.1 HTTPS 基础配置
nginx
# ===== HTTPS 配置 =====
# 文件:/etc/nginx/conf.d/ssl.conf
server {
listen 443 ssl http2; # 启用 HTTP/2
server_name example.com www.example.com;
# ----- SSL 证书配置 -----
ssl_certificate /etc/nginx/ssl/example.com.crt; # 证书文件
ssl_certificate_key /etc/nginx/ssl/example.com.key; # 私钥文件
# ----- SSL 协议配置 -----
ssl_protocols TLSv1.2 TLSv1.3; # 只启用安全的协议
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';
# ----- SSL 优化 -----
ssl_session_cache shared:SSL:10m; # SSL 会话缓存
ssl_session_timeout 10m; # 会话缓存超时
ssl_session_tickets off; # 禁用会话票据(更安全)
# ----- HSTS(强制 HTTPS)-----
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
# ----- OCSP Stapling(证书状态检查)-----
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# ----- 根目录配置 -----
root /usr/share/nginx/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
# ----- HTTP 重定向到 HTTPS -----
server {
listen 80;
server_name example.com www.example.com;
# 301 永久重定向
return 301 https://$server_name$request_uri;
}
3.2 Let's Encrypt 自动证书
bash
# ===== 使用 Certbot 获取免费证书 =====
# 1. 安装 Certbot
# Ubuntu/Debian
sudo apt update
sudo apt install certbot python3-certbot-nginx
# CentOS/RHEL
sudo yum install certbot python3-certbot-nginx
# 2. 获取证书(自动配置 Nginx)
sudo certbot --nginx -d example.com -d www.example.com
# 3. 手动获取证书(不自动配置)
sudo certbot certonly --nginx -d example.com -d www.example.com
# 4. 测试自动续期
sudo certbot renew --dry-run
# 5. 配置自动续期(cron)
echo "0 3 * * * /usr/bin/certbot renew --quiet" | sudo tee -a /etc/crontab
Certbot 自动生成的 Nginx 配置:
nginx
# Certbot 会自动添加以下配置
listen 443 ssl http2;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf; # SSL 参数
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # DH 参数
3.3 SSL 性能优化
nginx
# ===== SSL 性能优化配置 =====
# 添加到 http 块或 server 块
# 1. SSL 会话复用(减少握手开销)
ssl_session_cache shared:SSL:50m; # 共享缓存,50MB(约 40 万个会话)
ssl_session_timeout 1d; # 会话有效期 1 天
ssl_session_tickets off; # 禁用会话票据(提升安全性)
# 2. OCSP Stapling(减少客户端验证时间)
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/ssl/ca-bundle.crt; # CA 证书链
# 3. 启用 TLS 1.3(更快的握手)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off; # TLS 1.3 不需要偏好设置
# 4. 优化密钥交换(使用更强 DH 参数)
# 生成 2048 位 DH 参数(一次性操作)
# openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
# 5. 减少 TLS 记录开销
ssl_buffer_size 4k; # 减少首字节时间(适合小资源)
# 6. 启用 Early Data(TLS 1.3 0-RTT)
# 注意:可能有重放攻击风险
# ssl_early_data on;
SSL 性能对比:
| 优化项 | 效果 | 说明 |
|---|---|---|
| SSL 会话复用 | 减少 1-2 个 RTT | 显著提升重复访问性能 |
| OCSP Stapling | 减少 1 个 RTT | 客户端无需独立验证证书 |
| TLS 1.3 | 减少 1 个 RTT | 握手更快 |
| HTTP/2 | 多路复用 | 减少连接数 |
| 优化加密套件 | 提升 10-20% | 使用 AES-NI 硬件加速 |
四、缓存优化配置
4.1 代理缓存(Proxy Cache)
nginx
# ===== 代理缓存配置 =====
# 文件:/etc/nginx/conf.d/cache.conf
# ----- 1. 定义缓存区域 -----
http {
# 缓存路径:/var/cache/nginx
# levels=1:2(两级目录,减少单目录文件数)
# keys_zone=cache_one:10m(共享内存区域,10MB)
# max_size=10g(磁盘缓存最大 10GB)
# inactive=60m(60 分钟未访问则删除)
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=cache_one:10m max_size=10g inactive=60m use_temp_path=off;
# 缓存加载参数(重启后逐步加载缓存,避免 IO 峰值)
proxy_cache_path /var/cache/nginx/tmp levels=1:2 keys_zone=cache_tmp:1m max_size=1g inactive=10m;
# ----- 2. 缓存配置 -----
server {
listen 80;
server_name cache.example.com;
# 上游服务器
upstream backend {
server 192.168.1.101:8080;
server 192.168.1.102:8080;
}
location / {
proxy_pass http://backend;
# 启用缓存
proxy_cache cache_one;
# 缓存 Key(根据什么区分缓存)
proxy_cache_key $scheme$request_method$host$request_uri;
# 缓存有效期(根据状态码)
proxy_cache_valid 200 302 10m; # 成功响应缓存 10 分钟
proxy_cache_valid 404 1m; # 404 缓存 1 分钟
proxy_cache_valid any 5m; # 其他状态码缓存 5 分钟
# 缓存绕过条件
proxy_cache_bypass $cookie_session $http_authorization;
proxy_no_cache $cookie_session $http_authorization;
# 添加缓存状态头(调试用)
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_lock on; # 防止缓存击穿(多个请求同时回源)
}
# ----- 3. 不缓存的配置 -----
location /api/ {
proxy_pass http://backend;
# 不缓存 API(实时数据)
proxy_cache off;
# 但缓存错误响应
proxy_cache_valid 500 502 503 504 1m;
}
# ----- 4. 清除缓存(需要 purge 模块)-----
location ~ /purge(/.*) {
# 只允许特定 IP 清除缓存
allow 127.0.0.1;
deny all;
proxy_cache_purge cache_one $scheme$request_method$host$1;
}
}
}
4.2 浏览器缓存(静态资源)
nginx
# ===== 浏览器缓存配置 =====
server {
listen 80;
server_name static.example.com;
root /usr/share/nginx/static;
# ----- 1. 图片缓存(长期)-----
location ~* \.(jpg|jpeg|png|gif|ico|webp)$ {
expires 1y; # 缓存 1 年
add_header Cache-Control "public, immutable"; # 不可变资源
access_log off; # 关闭访问日志(提升性能)
tcp_nodelay off; # 优化大文件传输
}
# ----- 2. CSS/JS 缓存(中等)-----
location ~* \.(css|js)$ {
expires 30d; # 缓存 30 天
add_header Cache-Control "public";
access_log off;
}
# ----- 3. HTML 不缓存(始终从服务器获取)-----
location ~* \.html$ {
expires -1; # 不缓存
add_header Cache-Control "no-cache";
}
# ----- 4. 字体文件缓存 -----
location ~* \.(woff|woff2|ttf|eot|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# ----- 5. 版本化资源(带 hash)-----
# 例如:app.8f3a9b2c.js
location ~* \.[a-f0-9]{8,}\.(css|js)$ {
expires max; # 永久缓存
add_header Cache-Control "public, immutable";
access_log off;
}
}
4.3 FastCGI 缓存(PHP 应用)
nginx
# ===== FastCGI 缓存(PHP-FPM)=====
# 适用于 WordPress、Laravel 等 PHP 应用
# 1. 定义 FastCGI 缓存
fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=php_cache:10m max_size=10g inactive=60m;
# 2. 缓存配置
server {
listen 80;
server_name wordpress.example.com;
root /var/www/wordpress;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# 启用 FastCGI 缓存
fastcgi_cache php_cache;
fastcgi_cache_key $scheme$request_method$host$request_uri;
fastcgi_cache_valid 200 302 10m;
fastcgi_cache_valid 404 1m;
fastcgi_cache_use_stale error timeout updating http_500 http_503;
# 跳过缓存条件
fastcgi_cache_bypass $cookie_wordpress_logged_in $http_authorization;
fastcgi_no_cache $cookie_wordpress_logged_in $http_authorization;
# 添加缓存状态头
add_header X-FastCGI-Cache $upstream_cache_status;
}
}
五、性能调优
5.1 核心参数优化
nginx
# ===== Nginx 性能优化 =====
# 文件:/etc/nginx/nginx.conf
# ----- 1. Worker 进程优化 -----
user nginx;
worker_processes auto; # 自动设置为 CPU 核心数
worker_cpu_affinity auto; # CPU 亲和性(绑定 CPU)
worker_priority -10; # Worker 进程优先级(-20 到 19)
worker_rlimit_nofile 65535; # Worker 进程最大打开文件数
# ----- 2. Events 优化 -----
events {
worker_connections 65535; # 每个 Worker 最大连接数
use epoll; # Linux 使用 epoll(高效)
multi_accept on; # 一次接受多个连接
accept_mutex off; # 禁用互斥锁(高并发时)
}
# ----- 3. HTTP 核心优化 -----
http {
# 3.1 文件描述符优化
open_file_cache max=10000 inactive=30s; # 缓存文件描述符
open_file_cache_valid 60s; # 缓存有效期
open_file_cache_min_uses 2; # 最少访问 2 次才缓存
open_file_cache_errors on; # 缓存文件错误
# 3.2 连接优化
keepalive_timeout 65; # 长连接超时
keepalive_requests 1000; # 单个连接最大请求数
reset_timedout_connection on; # 重置超时连接
# 3.3 客户端优化
client_max_body_size 100m; # 最大上传文件大小
client_body_buffer_size 128k; # 请求体缓冲区
client_header_buffer_size 4k; # 请求头缓冲区
large_client_header_buffers 4 16k; # 大请求头缓冲区
# 3.4 响应优化
output_buffers 2 32k; # 输出缓冲区
postpone_output 1460; # 延迟输出(凑够一个包)
# 3.5 零拷贝优化
sendfile on; # 启用零拷贝
tcp_nopush on; # 优化网络传输(合并包)
tcp_nodelay on; # 禁用 Nagle 算法(小包立即发送)
# 3.6 超时优化
client_header_timeout 15s; # 请求头超时
client_body_timeout 15s; # 请求体超时
send_timeout 10s; # 发送超时
}
5.2 Gzip 压缩优化
nginx
# ===== Gzip 压缩配置 =====
http {
# 1. 启用 Gzip
gzip on;
gzip_vary on; # 添加 Vary: Accept-Encoding 头
gzip_proxied any; # 为所有代理请求启用压缩
# 2. 压缩级别(1-9,越高压缩率越好但越慢)
gzip_comp_level 5; # 推荐 5(平衡)
# 3. 压缩类型
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript application/x-javascript;
# 4. 压缩条件
gzip_min_length 1024; # 小于 1KB 不压缩
gzip_disable "msie6"; # IE6 不支持 Gzip
gzip_http_version 1.1; # 最低 HTTP 版本
# 5. 缓冲区
gzip_buffers 16 8k; # 压缩缓冲区
# 6. 针对代理的优化
gzip_proxied expired no-cache no-store private auth;
}
5.3 浏览器缓存与 Gzip 对比
| 优化项 | 效果 | 适用场景 |
|---|---|---|
| 浏览器缓存 | 减少请求 | 静态资源(图片、CSS、JS) |
| Gzip 压缩 | 减少传输大小 | 文本类资源(HTML、CSS、JS、JSON) |
| 代理缓存 | 减少后端请求 | 动态内容(API、页面) |
| HTTP/2 | 多路复用 | 高并发场景 |
六、安全防护
6.1 基础安全配置
nginx
# ===== Nginx 安全配置 =====
server {
listen 80;
server_name secure.example.com;
# ----- 1. 隐藏 Nginx 版本 -----
server_tokens off; # 隐藏版本号(在 http 块配置)
# ----- 2. 防止点击劫持 -----
add_header X-Frame-Options "SAMEORIGIN" always;
# ----- 3. 防止 MIME 类型嗅探 -----
add_header X-Content-Type-Options "nosniff" always;
# ----- 4. XSS 防护 -----
add_header X-XSS-Protection "1; mode=block" always;
# ----- 5. 强制下载(防止执行)-----
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';" always;
# ----- 6. 限制请求方法 -----
if ($request_method !~ ^(GET|POST|HEAD)$) {
return 405; # Method Not Allowed
}
# ----- 7. 防止图片盗链 -----
location ~* \.(jpg|jpeg|png|gif|ico|webp)$ {
valid_referers none blocked server_names *.example.com;
if ($invalid_referer) {
return 403; # Forbidden
}
}
# ----- 8. 限制访问频率(防 CC 攻击)-----
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s; # 限制 10 请求/秒
limit_req zone=one burst=20 nodelay; # 允许突发 20 个请求
# ----- 9. 限制连接数(防并发攻击)-----
limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_conn addr 10; # 每个 IP 最多 10 个连接
# ----- 10. 白名单/黑名单 -----
# 允许特定 IP
allow 192.168.1.0/24;
allow 10.0.0.0/8;
deny all; # 拒绝其他 IP
location / {
# 主应用配置
}
}
6.2 防 DDoS 攻击
nginx
# ===== 防 DDoS 配置 =====
http {
# 1. 限制请求频率(全局)
limit_req_zone $binary_remote_addr zone=global:20m rate=100r/s;
# 2. 限制连接数(全局)
limit_conn_zone $binary_remote_addr zone=conn_limit:20m;
server {
# 3. 应用限制
limit_req zone=global burst=50 nodelay;
limit_conn conn_limit 20;
# 4. 慢连接攻击防护
client_body_timeout 10s;
client_header_timeout 10s;
send_timeout 10s;
# 5. 限制 User-Agent(拦截恶意爬虫)
if ($http_user_agent ~* "Scrapy|Python|curl|Wget|bot") {
return 403;
}
location / {
# 主应用配置
}
}
}
七、日志与监控
7.1 日志配置
nginx
# ===== 日志配置 =====
http {
# ----- 1. 自定义日志格式 -----
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"';
# ----- 2. 访问日志 -----
access_log /var/log/nginx/access.log main buffer=32k flush=5s;
# ----- 3. 错误日志 -----
error_log /var/log/nginx/error.log warn; # 级别:debug|info|notice|warn|error|crit|alert|emerg
# ----- 4. 条件日志(不记录特定请求)-----
map $status $loggable {
200 0; # 不记录 200 响应
204 0;
default 1;
}
access_log /var/log/nginx/access.log main if=$loggable;
# ----- 5. 按域名分日志 -----
server {
server_name site1.example.com;
access_log /var/log/nginx/site1.access.log main;
error_log /var/log/nginx/site1.error.log;
}
server {
server_name site2.example.com;
access_log /var/log/nginx/site2.access.log main;
error_log /var/log/nginx/site2.error.log;
}
}
7.2 状态监控
nginx
# ===== Nginx 状态监控 =====
server {
listen 80;
server_name monitor.example.com;
# ----- 1. 基础状态(stub_status 模块)-----
location /basic_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
# ----- 2. 高级监控(需要 nginx-plus 或第三方模块)-----
# 可以使用 nginx-module-vts 或 nginx-amplify
# ----- 3. 健康检查 -----
location /health {
access_log off;
return 200 "OK\n";
add_header Content-Type text/plain;
}
}
使用 GoAccess 分析日志:
bash
# 1. 安装 GoAccess
sudo apt install goaccess
# 2. 实时分析访问日志
goaccess /var/log/nginx/access.log -c --real-time-html -o /var/www/html/report.html
# 3. 生成静态报告
goaccess /var/log/nginx/access.log -o /var/www/html/report.html --log-format=COMBINED
八、实战:完整生产配置
8.1 生产级 Nginx 配置
nginx
# ===== 生产级 Nginx 配置 =====
# 文件:/etc/nginx/nginx.conf
# ----- 全局配置 -----
user nginx;
worker_processes auto;
worker_cpu_affinity auto;
worker_priority -10;
worker_rlimit_nofile 65535;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
# ----- Events 配置 -----
events {
worker_connections 65535;
use epoll;
multi_accept on;
accept_mutex off;
}
# ----- HTTP 配置 -----
http {
# 基础配置
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 日志格式
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 upt="$upstream_response_time"';
access_log /var/log/nginx/access.log main buffer=32k flush=5s;
# 性能优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
keepalive_requests 1000;
# 文件缓存
open_file_cache max=10000 inactive=30s;
open_file_cache_valid 60s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
# Gzip 压缩
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
# 客户端优化
client_max_body_size 100m;
client_body_buffer_size 128k;
client_header_buffer_size 4k;
large_client_header_buffers 4 16k;
# 代理缓存
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=cache_one:10m max_size=10g inactive=60m;
# 限流
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=addr:10m;
# 引入站点配置
include /etc/nginx/conf.d/*.conf;
}
# ===== 站点配置 =====
# 文件:/etc/nginx/conf.d/example.com.conf
# ----- HTTP 重定向到 HTTPS -----
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
# ----- HTTPS 配置 -----
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# SSL 配置
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# 安全头
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
# 根目录
root /var/www/example.com;
index index.html;
# 静态资源缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff2)$ {
expires 30d;
add_header Cache-Control "public";
access_log off;
}
# 主应用
location / {
try_files $uri $uri/ /index.html;
}
# API 反向代理
location /api/ {
proxy_pass http://backend;
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_cache cache_one;
proxy_cache_valid 200 10m;
add_header X-Cache-Status $upstream_cache_status;
}
}
# ----- 上游服务器 -----
upstream backend {
least_conn;
server 192.168.1.101:8080 weight=3;
server 192.168.1.102:8080 weight=2;
server 192.168.1.103:8080 weight=1;
}
九、常见问题排查
9.1 问题诊断流程
#mermaid-svg-14wnnY3iKTRdH0Z4{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-14wnnY3iKTRdH0Z4 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-14wnnY3iKTRdH0Z4 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-14wnnY3iKTRdH0Z4 .error-icon{fill:#552222;}#mermaid-svg-14wnnY3iKTRdH0Z4 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-14wnnY3iKTRdH0Z4 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-14wnnY3iKTRdH0Z4 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-14wnnY3iKTRdH0Z4 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-14wnnY3iKTRdH0Z4 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-14wnnY3iKTRdH0Z4 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-14wnnY3iKTRdH0Z4 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-14wnnY3iKTRdH0Z4 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-14wnnY3iKTRdH0Z4 .marker.cross{stroke:#333333;}#mermaid-svg-14wnnY3iKTRdH0Z4 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-14wnnY3iKTRdH0Z4 p{margin:0;}#mermaid-svg-14wnnY3iKTRdH0Z4 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-14wnnY3iKTRdH0Z4 .cluster-label text{fill:#333;}#mermaid-svg-14wnnY3iKTRdH0Z4 .cluster-label span{color:#333;}#mermaid-svg-14wnnY3iKTRdH0Z4 .cluster-label span p{background-color:transparent;}#mermaid-svg-14wnnY3iKTRdH0Z4 .label text,#mermaid-svg-14wnnY3iKTRdH0Z4 span{fill:#333;color:#333;}#mermaid-svg-14wnnY3iKTRdH0Z4 .node rect,#mermaid-svg-14wnnY3iKTRdH0Z4 .node circle,#mermaid-svg-14wnnY3iKTRdH0Z4 .node ellipse,#mermaid-svg-14wnnY3iKTRdH0Z4 .node polygon,#mermaid-svg-14wnnY3iKTRdH0Z4 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-14wnnY3iKTRdH0Z4 .rough-node .label text,#mermaid-svg-14wnnY3iKTRdH0Z4 .node .label text,#mermaid-svg-14wnnY3iKTRdH0Z4 .image-shape .label,#mermaid-svg-14wnnY3iKTRdH0Z4 .icon-shape .label{text-anchor:middle;}#mermaid-svg-14wnnY3iKTRdH0Z4 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-14wnnY3iKTRdH0Z4 .rough-node .label,#mermaid-svg-14wnnY3iKTRdH0Z4 .node .label,#mermaid-svg-14wnnY3iKTRdH0Z4 .image-shape .label,#mermaid-svg-14wnnY3iKTRdH0Z4 .icon-shape .label{text-align:center;}#mermaid-svg-14wnnY3iKTRdH0Z4 .node.clickable{cursor:pointer;}#mermaid-svg-14wnnY3iKTRdH0Z4 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-14wnnY3iKTRdH0Z4 .arrowheadPath{fill:#333333;}#mermaid-svg-14wnnY3iKTRdH0Z4 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-14wnnY3iKTRdH0Z4 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-14wnnY3iKTRdH0Z4 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-14wnnY3iKTRdH0Z4 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-14wnnY3iKTRdH0Z4 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-14wnnY3iKTRdH0Z4 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-14wnnY3iKTRdH0Z4 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-14wnnY3iKTRdH0Z4 .cluster text{fill:#333;}#mermaid-svg-14wnnY3iKTRdH0Z4 .cluster span{color:#333;}#mermaid-svg-14wnnY3iKTRdH0Z4 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-14wnnY3iKTRdH0Z4 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-14wnnY3iKTRdH0Z4 rect.text{fill:none;stroke-width:0;}#mermaid-svg-14wnnY3iKTRdH0Z4 .icon-shape,#mermaid-svg-14wnnY3iKTRdH0Z4 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-14wnnY3iKTRdH0Z4 .icon-shape p,#mermaid-svg-14wnnY3iKTRdH0Z4 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-14wnnY3iKTRdH0Z4 .icon-shape .label rect,#mermaid-svg-14wnnY3iKTRdH0Z4 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-14wnnY3iKTRdH0Z4 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-14wnnY3iKTRdH0Z4 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-14wnnY3iKTRdH0Z4 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 无法启动
访问慢
502/503
403
404
Nginx 异常
问题类型?
配置文件错误
性能问题
上游服务器问题
权限问题
路径问题
nginx -t
查看错误日志
查看 status
检查缓存
优化配置
检查 upstream
测试上游服务器
检查文件权限
检查 SELinux
检查 root 路径
检查 location 匹配
9.2 常用调试命令
bash
# ----- 1. 配置检查 -----
# 检查配置文件语法
sudo nginx -t
# 检查特定配置文件
sudo nginx -t -c /etc/nginx/nginx.conf
# ----- 2. 服务管理 -----
# 启动 Nginx
sudo systemctl start nginx
# 停止 Nginx
sudo systemctl stop nginx
# 重启 Nginx
sudo systemctl restart nginx
# 平滑重载配置(不中断服务)
sudo systemctl reload nginx
sudo nginx -s reload
# 查看状态
sudo systemctl status nginx
# ----- 3. 日志查看 -----
# 实时查看访问日志
tail -f /var/log/nginx/access.log
# 实时查看错误日志
tail -f /var/log/nginx/error.log
# 查看特定 IP 的访问记录
grep "192.168.1.100" /var/log/nginx/access.log
# 统计访问量 Top 10 IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
# ----- 4. 性能测试 -----
# 安装 ab(ApacheBench)
sudo apt install apache2-utils
# 压力测试(1000 请求,10 并发)
ab -n 1000 -c 10 http://example.com/
# 安装 wrk(更强大的压测工具)
sudo apt install wrk
# 压测(10 并发,30 秒)
wrk -t10 -c100 -d30s http://example.com/
# ----- 5. 连接查看 -----
# 查看 Nginx 进程
ps aux | grep nginx
# 查看连接数
netstat -an | grep :80 | wc -l
# 查看 ESTABLISHED 连接
netstat -an | grep ESTABLISHED | wc -l
# 查看 Nginx 状态(需要配置 stub_status)
curl http://localhost/basic_status
9.3 常见错误与解决
| 错误 | 原因 | 解决方案 |
|---|---|---|
| nginx: emerg bind() to 0.0.0.0:80 failed (98: Address already in use) | 端口被占用 | sudo fuser -k 80/tcp 然后重启 |
| 403 Forbidden | 权限不足 | 检查目录/文件权限,检查 SELinux |
| 404 Not Found | 路径错误 | 检查 root 和 location 配置 |
| 502 Bad Gateway | 上游服务器不可用 | 检查 upstream 服务器状态 |
| 504 Gateway Timeout | 上游服务器响应慢 | 增加 proxy_read_timeout |
| 静态资源访问不到 | 路径或权限问题 | 检查 root 路径,检查文件权限 |
| HTTPS 证书错误 | 证书配置错误 | 检查证书路径、权限、有效期 |
十、总结与最佳实践
10.1 配置检查清单
#mermaid-svg-y3TKuwHIvZgoNHSQ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-y3TKuwHIvZgoNHSQ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-y3TKuwHIvZgoNHSQ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-y3TKuwHIvZgoNHSQ .error-icon{fill:#552222;}#mermaid-svg-y3TKuwHIvZgoNHSQ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-y3TKuwHIvZgoNHSQ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-y3TKuwHIvZgoNHSQ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-y3TKuwHIvZgoNHSQ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-y3TKuwHIvZgoNHSQ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-y3TKuwHIvZgoNHSQ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-y3TKuwHIvZgoNHSQ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-y3TKuwHIvZgoNHSQ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-y3TKuwHIvZgoNHSQ .marker.cross{stroke:#333333;}#mermaid-svg-y3TKuwHIvZgoNHSQ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-y3TKuwHIvZgoNHSQ p{margin:0;}#mermaid-svg-y3TKuwHIvZgoNHSQ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-y3TKuwHIvZgoNHSQ .cluster-label text{fill:#333;}#mermaid-svg-y3TKuwHIvZgoNHSQ .cluster-label span{color:#333;}#mermaid-svg-y3TKuwHIvZgoNHSQ .cluster-label span p{background-color:transparent;}#mermaid-svg-y3TKuwHIvZgoNHSQ .label text,#mermaid-svg-y3TKuwHIvZgoNHSQ span{fill:#333;color:#333;}#mermaid-svg-y3TKuwHIvZgoNHSQ .node rect,#mermaid-svg-y3TKuwHIvZgoNHSQ .node circle,#mermaid-svg-y3TKuwHIvZgoNHSQ .node ellipse,#mermaid-svg-y3TKuwHIvZgoNHSQ .node polygon,#mermaid-svg-y3TKuwHIvZgoNHSQ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-y3TKuwHIvZgoNHSQ .rough-node .label text,#mermaid-svg-y3TKuwHIvZgoNHSQ .node .label text,#mermaid-svg-y3TKuwHIvZgoNHSQ .image-shape .label,#mermaid-svg-y3TKuwHIvZgoNHSQ .icon-shape .label{text-anchor:middle;}#mermaid-svg-y3TKuwHIvZgoNHSQ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-y3TKuwHIvZgoNHSQ .rough-node .label,#mermaid-svg-y3TKuwHIvZgoNHSQ .node .label,#mermaid-svg-y3TKuwHIvZgoNHSQ .image-shape .label,#mermaid-svg-y3TKuwHIvZgoNHSQ .icon-shape .label{text-align:center;}#mermaid-svg-y3TKuwHIvZgoNHSQ .node.clickable{cursor:pointer;}#mermaid-svg-y3TKuwHIvZgoNHSQ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-y3TKuwHIvZgoNHSQ .arrowheadPath{fill:#333333;}#mermaid-svg-y3TKuwHIvZgoNHSQ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-y3TKuwHIvZgoNHSQ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-y3TKuwHIvZgoNHSQ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-y3TKuwHIvZgoNHSQ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-y3TKuwHIvZgoNHSQ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-y3TKuwHIvZgoNHSQ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-y3TKuwHIvZgoNHSQ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-y3TKuwHIvZgoNHSQ .cluster text{fill:#333;}#mermaid-svg-y3TKuwHIvZgoNHSQ .cluster span{color:#333;}#mermaid-svg-y3TKuwHIvZgoNHSQ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-y3TKuwHIvZgoNHSQ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-y3TKuwHIvZgoNHSQ rect.text{fill:none;stroke-width:0;}#mermaid-svg-y3TKuwHIvZgoNHSQ .icon-shape,#mermaid-svg-y3TKuwHIvZgoNHSQ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-y3TKuwHIvZgoNHSQ .icon-shape p,#mermaid-svg-y3TKuwHIvZgoNHSQ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-y3TKuwHIvZgoNHSQ .icon-shape .label rect,#mermaid-svg-y3TKuwHIvZgoNHSQ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-y3TKuwHIvZgoNHSQ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-y3TKuwHIvZgoNHSQ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-y3TKuwHIvZgoNHSQ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Nginx 配置检查清单
基础配置
性能优化
安全加固
监控日志
✅ worker_processes 设置
✅ worker_connections 设置
✅ 日志格式配置
✅ Gzip 压缩启用
✅ 浏览器缓存配置
✅ 代理缓存配置
✅ 文件描述符缓存
✅ 隐藏版本号
✅ 安全头配置
✅ 限流配置
✅ SSL/TLS 优化
✅ 访问日志
✅ 错误日志
✅ 状态监控
10.2 性能优化建议
| 优化项 | 建议 | 效果 |
|---|---|---|
| Worker 进程 | worker_processes auto |
充分利用 CPU |
| 连接数 | worker_connections 65535 |
支持高并发 |
| Gzip 压缩 | gzip_comp_level 5 |
减少传输大小 |
| 浏览器缓存 | 静态资源缓存 30d+ | 减少请求 |
| 代理缓存 | 启用 proxy_cache |
减少后端压力 |
| SSL 优化 | 启用 TLS 1.3 + 会话复用 | 提升 HTTPS 性能 |
| HTTP/2 | listen 443 ssl http2 |
多路复用 |
10.3 安全加固建议
| 加固项 | 建议 | 说明 |
|---|---|---|
| 隐藏版本 | server_tokens off |
防止版本泄露 |
| 安全头 | 配置 HSTS、X-Frame-Options 等 | 防止常见攻击 |
| 限流 | limit_req + limit_conn |
防 DDoS/CC |
| SSL/TLS | 禁用 TLS 1.0/1.1 | 提升安全性 |
| 权限控制 | 最小化文件权限 | 防止提权 |
附录:常用配置模板
A. 反向代理模板
nginx
location / {
proxy_pass http://backend;
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 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_cache cache_one;
proxy_cache_valid 200 10m;
add_header X-Cache-Status $upstream_cache_status;
}
B. 静态资源模板
nginx
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff2)$ {
expires 30d;
add_header Cache-Control "public";
access_log off;
tcp_nodelay off;
}
C. HTTPS 模板
nginx
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# HTTP 重定向
if ($scheme = http) {
return 301 https://$server_name$request_uri;
}
}
本文基于 Nginx 1.20+ 编写,不同版本配置可能略有差异。建议读者结合实际环境调整参数。如有问题欢迎评论区讨论!