我把前端从 /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% 的线上故障都能提前消失。

相关推荐
wewowilling5 分钟前
认识微服务
java·运维·微服务·springcloud
玖石书13 分钟前
Ubuntu 24.04 UFW 全命令攻略:从入门到端口开放实战
linux·运维·ubuntu
高晶22 分钟前
Android 新手实战:从零搭建 WebRTC 在线直播系统
android·程序员
weifont2 小时前
自动化抓取和上架商品:能不动手,就少动手
运维·前端·自动化
拂拉氏2 小时前
【知识讲解】 Linux之动静态库的了解
linux·运维·服务器·动静态库
Mikko73 小时前
Linux 重启后日志没了?进程被 OOM 杀了去哪看?logrotate 之后日志还往旧文件写?三台真机实测日志与性能排查
linux·运维·centos
光依旧3 小时前
发版就掉请求?Spring Boot优雅停机的四步
运维·spring boot·nginx·高可用·优雅停机·mcp server
寒狼GPT4 小时前
Codex 5小时额度是固定重置还是滚动恢复?为什么每个人Reset时间不一样
chatgpt·程序员·ai编程
yichengerp5 小时前
电子行业常用erp系统有哪些?推荐适合中小电子厂的易呈erp软件,操作简单,易落地
大数据·运维·人工智能·云计算·制造
天国梦5 小时前
国密门禁品牌怎么选?2026年最新3个避坑要点
运维·服务器·数据库·python