我把前端从 /ais 改到 /kb 后,连续踩了 7 个 Nginx 坑(含 405/413/502/404 终极解法)

大家好我是舒一笑不秃头,喜欢写作和分享,更多精彩内容

一句话总结:前端路径前缀、网关转发前缀、后端真实路径 这三件事如果没彻底对齐,线上一定会"随机炸"。


1. 背景:看起来只是改个前缀,实际上是链路重构

项目原来跑在 /ais,现在要挂到网关 :8000/kb/

同时后端有两套服务:

  • 主后端:188.104.159.164:10003
  • 预览服务:188.104.159.164:8012

前端请求统一走 /aiskb/...,再由 Nginx 分发到不同 upstream。


2. 我遇到的典型故障(你大概率也会遇到)

  1. 502 Connection refused

    原因:容器里转发到了 127.0.0.1:10003,但后端不在容器内。

  2. 405 Not Allowed

    原因:请求没命中 API location,掉进了静态 location /kb/,POST 被静态资源处理逻辑拒绝。

  3. 413 Request Entity Too Large

    原因:Nginx 默认 body 太小(常见 1m)。

  4. 前端登录页 404

    原因:后端返回 Location: /login,但前端实际部署在 /kb/login

  5. /kb/license/validate 被重写成 /license/validate

    原因:rewrite 写猛了,把后端真实需要的 /kb 也干掉了。

  6. 预览接口走错后端

    原因:/kl/api/saas/element/preview/* 应该去 8012,却被通用规则发到 10003

  7. 以为是 Host 丢失导致 405

    结论:不是。405 多数是路由命中错误,不是 Host 头问题。


3. 核心原则(非常关键)

  1. 前端前缀、网关前缀、后端真实路径,必须逐条列清楚。
  2. 精确路由必须放在通用路由之前(^~ + 顺序)。
  3. 只改该改的前缀,不要全局无脑 rewrite。
  4. 登录跳转要做 proxy_redirect 或兜底重定向兼容。
  5. 上传场景必须显式设置 client_max_body_size

4. 可直接落地的 Nginx 配置(我线上用的结构)

nginx 复制代码
upstream ais_backend {
    server 188.104.159.164:10003;
}

upstream ais_preview {
    server 188.104.159.164:8012;
}

server {
    listen 8000;
    server_name _;
    root /usr/share/nginx/html;
    index index.html index.htm;
    client_max_body_size 2g;

    location = / { return 301 /kb/; }
    location = /kb { return 301 /kb/; }

    # 预览服务:必须放在通用 /aiskb/ 之前
    location ^~ /aiskb/kl/api/saas/element/preview/ {
        rewrite ^/aiskb/(.*)$ /$1 break;
        proxy_pass http://ais_preview;
        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;
    }

    # 通用 API
    location ^~ /aiskb/ {
        rewrite ^/aiskb/(.*)$ /$1 break;
        proxy_pass http://ais_backend;
        proxy_redirect ~^/(login|register|sso|home)(/.*)?$ /kb/$1$2;
        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;
    }

    # 兼容后端真实需要 /kb 的接口(不要 rewrite 掉 /kb)
    location ^~ /kb/license/ {
        proxy_pass http://ais_backend;
        proxy_redirect ~^/(login|register|sso|home)(/.*)?$ /kb/$1$2;
        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;
    }

    # 后端静态兼容
    location ^~ /kb/ais/ {
        rewrite ^/kb/(ais/.*)$ /$1 break;
        proxy_pass http://ais_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;
    }

    location ^~ /ais/ {
        proxy_pass http://ais_backend;
        proxy_redirect ~^/(login|register|sso|home)(/.*)?$ /kb/$1$2;
        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;
    }

    # 后端返回 /login 时的前端兼容
    location ~ ^/(login|register|sso|home)(/.*)?$ {
        return 302 /kb$uri$is_args$args;
    }

    # 前端 SPA
    location /kb/ {
        rewrite ^/kb/(.*)$ /$1 break;
        try_files $uri $uri/ /index.html;
    }
}

5. 排错顺序(建议收藏)

  1. 先看浏览器 Network:状态码 + Request URL + Method。
  2. 再看 Nginx access/error:确认实际命中的 location 和 upstream。
  3. 再核对 rewrite 前后 URI 是否符合后端 Controller。
  4. 大文件上传先排 Nginx 413,再排后端 multipart 限制。
  5. 登录跳转问题优先看 Location 响应头。

6. 最后一句

这类问题本质不是"会不会写 Nginx",而是你有没有把 路径语义 设计清楚。

只要把"入口路径、网关路径、后端真实路径、重写规则、优先级"画成一张表,80% 的线上故障都能提前消失。

相关推荐
IVEN_33 分钟前
记一次诡异的前端白屏故障:Nginx Proxy Cache 内存缓存"幽灵"事件
前端·nginx
asyxchenchong8881 小时前
最新Hermes Agent 技能封装与科研自动化:以 Meta-Analysis 为例-实现从文献检索到绘图的一站式工作流
运维·人工智能·自动化
tianyuanwo1 小时前
项目内自我管理:一名OS领域DevOps的破局之路
运维·devops
三十..1 小时前
Redis 核心原理与高可用架构实践
运维·数据库·redis
jinglong.zha4 小时前
LScript-从零基础到商业变现的AI自动化学习平台
运维·学习·自动化
Adorable老犀牛4 小时前
Telegraf:InfluxData 出品的指标采集代理
运维·telegraf
北塔软件4 小时前
北塔软件智能体平台 | 不只监控,更是AI时代的数据资产
运维·人工智能·知识库·北塔软件
AOwhisky5 小时前
学习自测与解析:MySQL第五、六、七期核心知识点详解
运维·数据库·笔记·学习·mysql·云计算
无限进步_5 小时前
从零实现一个迷你Shell——深入理解Linux命令行解释器
linux·运维·服务器·开发语言·c++·chrome
Adorable老犀牛5 小时前
nginx_exporter:Prometheus 监控 Nginx 基础指标
运维·nginx·prometheus