Nginx 反向代理配置指南,看完这篇就够了

刚工作的时候,"Nginx"对我来说就是一个黑盒------运维配好我就用,出了问题只会重启。直到有一次线上 HTTPS 证书过期,整个排查过程我插不上手,才下决心自己学了一遍。

Nginx 是干什么的

简单说就三件事:

  • 静态文件服务:直接返回 HTML/CSS/JS/图片
  • 反向代理:把请求转发给后端服务(Tomcat、Node、Go 等)
  • 负载均衡:多个后端实例,Nginx 帮你分发请求

大部分项目里,Nginx 同时干这三件事。

核心配置文件结构

nginx 复制代码
# nginx.conf 主配置
worker_processes  auto;        # 工作进程数,auto = CPU 核数

events {
    worker_connections  1024;  # 每个进程最大连接数
}

http {
    include       mime.types;
    sendfile      on;          # 零拷贝传输,静态文件必开
    keepalive_timeout  65;

    # 虚拟主机 1
    server {
        listen       80;
        server_name  example.com;

        location / {
            root   /var/www/html;
            index  index.html;
        }
    }

    # 虚拟主机 2(反向代理)
    server {
        listen       80;
        server_name  api.example.com;

        location / {
            proxy_pass http://127.0.0.1:8080;
        }
    }
}

http → server → location 三层嵌套,每一层都可以有独立的配置。

反向代理配置

最基本的一条:

nginx 复制代码
server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;

        # 传递真实客户端信息给后端
        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_set_header 这四行基本是固定写法,不加的话后端拿到的 IP 全是 Nginx 的 127.0.0.1。

按路径转发到不同后端

nginx 复制代码
server {
    listen 80;
    server_name example.com;

    # API 请求 → Java 后端
    location /api/ {
        proxy_pass http://127.0.0.1:8080;
    }

    # WebSocket → Node 服务
    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";
    }

    # 静态文件 → 直接返回
    location / {
        root /var/www/frontend/dist;
        try_files $uri $uri/ /index.html;  # SPA 路由兜底
    }
}

try_files 那行是 SPA 标配------前端用 Vue Router / React Router 的 history 模式时,所有路径都要返回 index.html,否则刷新就 404。

HTTPS 配置

nginx 复制代码
server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate     /etc/nginx/ssl/example.com.pem;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;

    location / {
        proxy_pass http://127.0.0.1:8080;
    }
}

# HTTP 自动跳转 HTTPS
server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}

证书用 Let's Encrypt 免费申请,certbot 一行命令搞定续期。

负载均衡

nginx 复制代码
upstream backend {
    # 默认轮询
    server 192.168.1.10:8080 weight=3;  # 权重高的分更多请求
    server 192.168.1.11:8080 weight=1;
    server 192.168.1.12:8080 backup;    # 备用,前两台挂了才用

    # 也可以用 ip_hash(同一 IP 始终打到同一台,解决 session 问题)
    # ip_hash;

    # 或者 least_conn(请求最少的优先)
    # least_conn;
}

server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://backend;
    }
}
策略 说明 适用场景
轮询 (默认) 按顺序依次分发 后端实例性能一致
weight 按权重比例分发 后端性能不一致
ip_hash 同一 IP 固定到同一台 有 session 依赖
least_conn 优先分给连接数最少的 请求处理时间差异大

常用运维命令

bash 复制代码
# 测试配置文件语法
nginx -t

# 重新加载配置(不中断服务)
nginx -s reload

# 查看 Nginx 进程
ps aux | grep nginx

# 查看当前连接数
netstat -nlp | grep nginx

改完配置一定要先 nginx -t 测一下语法,再 nginx -s reload。直接 restart 会短暂中断连接。

踩坑:proxy_pass 末尾的斜杠

nginx 复制代码
# 有斜杠:/api/users → http://backend/users(去掉了 /api)
location /api/ {
    proxy_pass http://backend/;
}

# 没斜杠:/api/users → http://backend/api/users(保留 /api)
location /api/ {
    proxy_pass http://backend;
}

这个坑我见过不下三次,前后端联调的时候路径对不上,排查半天发现是斜杠的问题。记住:proxy_pass 后面有路径(哪怕只是一个 /),就会替换掉 location 的匹配部分。

总结

Nginx 日常用到的就是:反向代理(proxy_pass)、静态文件(root + try_files)、HTTPS(ssl_certificate)、负载均衡(upstream)。配完记得 nginx -t 测语法,proxy_pass 注意斜杠。

相关推荐
国际云,接待2 小时前
云服务器 WebSocket 空闲后频繁断开:查 Nginx 超时、心跳与负载均衡,再评估扩容
服务器·websocket·nginx
庵中十三居士1 天前
用nginx代理DeepSeekHarness挂在域名下特定路径提供访问
运维·nginx·deepseek·harness
fb_123451 天前
K8s 网络通关手册:Ingress-Nginx 生产级路由 + Calico 三种隧道模式 + NetworkPolicy 白名单实战
网络·nginx·kubernetes
承渊政道1 天前
新增一台服务器时还要重新装Nginx?Ansible只改hosts目标列表,同一份Playbook继续执行
运维·nginx·ansible·内网穿透·cpolar
KIDULT°1 天前
K8s 网络进阶实战:Ingress-Nginx、Calico 与 NetworkPolicy 实验 + 排坑记录
网络·nginx·云原生·kubernetes
姜鱼问生2 天前
网页一片白?Docker 跑 Nginx 读不到文件,403 Forbidden 排查实录
nginx·docker·容器
我不会起名字3224 天前
网关超时比服务短:一次 499 的完整归因
网关·nginx·排查·499
味悲4 天前
Nginx笔记
linux·运维·笔记·nginx
John_Hui4 天前
CentOS7安装Nginx
linux·服务器·nginx
时间售卖铺6 天前
Nginx 反向代理
运维·nginx·云原生