📖 知识点简介
Nginx 是当今互联网覆盖最广的 Web 服务器/反向代理软件,以高并发、低内存、配置灵活著称。无论是静态资源托管、反向代理、负载均衡,还是 SSL 终结、限流防爬,Nginx 都是运维工程师的"止血钳"------日常排障、服务发布几乎每天都离不开它。今天从安装→基础配置→反向代理→SSL→安全加固,一站式掌握 Nginx 运维核心技能。
🧰 核心命令整理
1. 安装与基本管理
bash
# CentOS / RHEL
yum install -y nginx
systemctl enable --now nginx
# Ubuntu / Debian
apt install -y nginx
systemctl enable --now nginx
# 常用管理命令
nginx -t # 测试配置语法(改配置前必执行!)
nginx -s reload # 热重载配置(不停机)
nginx -s stop # 停止
nginx -s reopen # 重新打开日志文件(日志切割后使用)
nginx -T # 打印完整配置文件(排错时看生效配置)
2. 核心配置结构解析
Nginx 配置采用指令式 + 层级继承模型,理解三层上下文是关键:
bash
main(全局配置)
├── events { ... } # 连接处理模型
└── http { ... } # HTTP 核心
├── server { ... } # 虚拟主机
│ ├── location / { ... } # URL 路由规则
│ └── location /api/ { ... }
└── server { ... } # 第二个虚拟主机
nginx
# /etc/nginx/nginx.conf --- 全局核心配置
user nginx;
worker_processes auto; # 自动匹配 CPU 核心数
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024; # 单 worker 最大连接数
multi_accept on; # 一次 accept 多个新连接
use epoll; # Linux 高性能 IO(默认自动)
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 性能调优
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
# 日志格式
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;
# Gzip 压缩
gzip on;
gzip_min_length 1000;
gzip_types text/plain text/css application/json application/javascript;
# 加载虚拟主机配置
include /etc/nginx/conf.d/*.conf;
}
3. 虚拟主机与 location 路由
nginx
# /etc/nginx/conf.d/blog.conf
server {
listen 80;
server_name blog.example.com;
root /var/www/blog;
index index.html;
location / {
try_files $uri $uri/ =404;
}
# 静态资源缓存
location ~* .(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
# 禁止访问隐藏文件
location ~ /. {
deny all;
access_log off;
log_not_found off;
}
}
| location 修饰符 | 含义 | 优先级 |
|---|---|---|
= /exact |
精确匹配 | 最高 |
^~ /prefix |
前缀匹配,一旦命中停止正则 | 次高 |
~ pattern |
大小写敏感正则 | 第三 |
~* pattern |
大小写不敏感正则 | 第四 |
| 无修饰 | 前缀匹配 | 最低 |
记忆口诀:= 精确最高,^~ 前缀第二,~ 正则第三,空格最次
🛠 实操示例
场景 1:反向代理 Node.js/Python 后端
nginx
# /etc/nginx/conf.d/api.example.com.conf
server {
listen 80;
server_name api.example.com;
# 后端 API 代理
location /api/ {
proxy_pass http://127.0.0.1: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 5s;
proxy_read_timeout 30s;
proxy_send_timeout 10s;
# 请求体大小限制
client_max_body_size 10m;
}
# WebSocket 支持(如 socket.io)
location /ws/ {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400s; # WebSocket 长连接
}
}
bash
# 验证配置并热加载
nginx -t && nginx -s reload
场景 2:配置 SSL(Let's Encrypt + 自动续签)
nginx
# /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 证书(推荐 certbot 获取)
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# 安全配置(2026 年推荐)
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_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
# HSTS(启用后浏览器强制 HTTPS)
add_header Strict-Transport-Security "max-age=63072000" always;
root /var/www/example;
index index.html;
}
bash
# 首次获取证书
dnf install certbot python3-certbot-nginx
certbot --nginx -d example.com -d www.example.com
# 自动续签(certbot 默认添加定时任务)
certbot renew --dry-run # 测试续签流程
systemctl list-timers | grep certbot # 确认续签定时器在跑
场景 3:负载均衡
nginx
# /etc/nginx/conf.d/load-balance.conf
upstream backend {
# 默认轮询(Round Robin)
server 10.0.0.1:8080 weight=3; # weight 越高分配越多
server 10.0.0.2:8080 weight=2;
server 10.0.0.3:8080 weight=1 backup; # 备用节点,前面挂了才启用
keepalive 32; # 连接池大小
}
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
include /etc/nginx/proxy_params; # 公共代理参数
}
}
nginx
# 其他负载均衡策略(替换 upstream 块内配置)
# 最小连接数(推荐长连接服务)
# least_conn;
# IP Hash(会话保持,避免轮询导致登录态丢失)
# ip_hash;
# 一致性 Hash(缓存场景最友好)
# hash $request_uri consistent;
⚠️ 常见坑点与注意事项
🔴 坑 1:proxy_pass 斜杠玄学
nginx
# ❌ 带了斜杠:去掉匹配的 location 前缀
location /api/ {
proxy_pass http://backend/;
# 请求 /api/users → 转发到 /users
}
# ✅ 不带斜杠:保留完整路径
location /api/ {
proxy_pass http://backend;
# 请求 /api/users → 转发到 /api/users
}
🔴 坑 2:nginx -t 通过但实际不生效
nginx -t只检查语法,不检查逻辑(如证书路径不存在、后端端口不通)- 养成习惯 :改完之后
nginx -t && nginx -s reload,再 curl 验证
🔴 坑 3:请求头超限 400 报错
nginx
# 现象:客户端请求头太大,Nginx 返回 400
# 解决:在 http/server 层加大限制
large_client_header_buffers 4 16k;
proxy_buffer_size 16k;
🔴 坑 4:SSL 证书到期未续签
bash
# 排查证书到期时间
openssl x509 -in /etc/letsencrypt/live/example.com/fullchain.pem -noout -enddate
# 设置监控(每天 crontab 检查)
0 6 * * * /usr/bin/openssl x509 -in /etc/letsencrypt/live/example.com/fullchain.pem -noout -enddate | awk -F= '{print $2}' | xargs -I {} sh -c 'if [ $(date -d "{}" +%s) -lt $(date +%s) ]; then echo "证书到期!"; fi'
🔴 坑 5:upstream 节点挂了后的排队雪崩
默认情况下,Nginx 不会主动检查后端健康状态。如果某节点挂了,请求仍然会转发过去直到连接超时,造成请求堆积。
nginx
# 启用主动健康检查(Nginx Plus 支持,开源版需用 ngx_http_upstream_check_module)
# 开源版变通方案:使用 proxy_next_upstream
location / {
proxy_pass http://backend;
proxy_next_upstream error timeout http_500 http_502 http_503;
proxy_next_upstream_tries 3; # 最多重试 3 个节点
proxy_next_upstream_timeout 10s; # 10s 内未找到健康节点则放弃
}
🔴 坑 6:隐藏 Nginx 版本号
nginx
# 在 http 块添加
server_tokens off;
# 验证
curl -I https://example.com
# Server: nginx ← 不再显示具体版本
📊 今日小结
| 主题 | 要点 | 一句话建议 |
|---|---|---|
| 安装管理 | nginx -t 必先执行 |
改配置三件套:test → reload → curl 验证 |
| 虚拟主机 | server_name 匹配 + location 优先级 | 用 default_server 兜底处理未匹配域名 |
| 反向代理 | proxy_pass + header 透传 | 斜杠决定路径是否被裁剪,一定要测试 |
| SSL | Let's Encrypt + 自动续签 | 证书到期监控比申请更重要 |
| 负载均衡 | upstream + weight + backup | 高可用场景加 proxy_next_upstream |