Nginx 配置与运维管理 — 从安装到 SSL 反向代理

📖 知识点简介

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
相关推荐
mqcode3 小时前
若依框架做大了怎么办?多模块 Maven 拆分的完整指南
后端
用户40269244819083 小时前
CRMEB Pro 新增后台接口全链路:路由、权限、验证器、返回格式一次讲清
前端·后端
考虑考虑3 小时前
Java实现hmacsha1加密算法
java·后端·java ee
程序边界4 小时前
lac_agent自愈链路上篇——crontab守护的那些坑与健康检查实战
后端
笨鸟飞不快4 小时前
从 MVC 到 DDD:一次真实的渐进式迁移实录
后端·架构
程序员威哥4 小时前
C#也能玩转YOLO:工业视觉原生推理方案,零Python依赖
后端
kfaino4 小时前
你好,我叫 Prompt——其实,你一直在给 AI 写程序
后端·openai·ai编程
caibixyy5 小时前
springboot+langchain4j实战Day 16 — 混合检索 + Reranker 重排序
后端
Ai拆代码的曹操5 小时前
揭秘"幽灵 CPU":top 抓不到的短命进程,才是真正的 CPU 杀手
后端