前后端 + Nginx + Gateway + K8s 全链路架构图解

一、先看全景架构图

先上图,你先有整体感。


1)用户访问系统的全链路图

XML 复制代码
               ┌──────────────────────────────┐
               │         用户浏览器            │
               │  访问: https://portal.xxx.com │
               └──────────────┬───────────────┘
                              │
                              │ 1. 通过域名访问
                              ▼
               ┌──────────────────────────────┐
               │       DNS / 本地 hosts        │
               │  portal.xxx.com -> 入口IP     │
               └──────────────┬───────────────┘
                              │
                              │ 2. 解析到入口IP
                              ▼
               ┌──────────────────────────────┐
               │     Nginx / Ingress入口层      │
               │  根据域名/路径决定转给谁       │
               └───────┬────────────────┬─────┘
                       │                │
             3a. / 页面资源             │ 3b. /api 接口请求
                       │                │
                       ▼                ▼
         ┌──────────────────┐   ┌────────────────────┐
         │   Front 服务      │   │   Gateway 服务      │
         │ (静态文件服务)    │   │ (API统一入口)       │
         └────────┬─────────┘   └─────────┬──────────┘
                  │                       │
                  │ 返回 index.html/js    │ 4. 按接口路由转发
                  ▼                       ▼
         ┌──────────────────┐   ┌────────────────────┐
         │ 浏览器渲染页面     │   │   Backend 服务群    │
         │ 执行前端JS代码     │   │ user/order/auth... │
         └────────┬─────────┘   └─────────┬──────────┘
                  │                       │
                  │ 5. 前端继续调接口      │ 6. 查库/执行业务
                  │                       ▼
                  │             ┌────────────────────┐
                  │             │      数据库/缓存     │
                  │             │ MySQL/Redis/ES等    │
                  │             └────────────────────┘
                  │
                  ▼
         ┌──────────────────┐
         │ 页面显示真实数据   │
         └──────────────────┘

2)如果放到 Kubernetes 里,关系图是这样的

XML 复制代码
                        集群外部
────────────────────────────────────────────────────────

浏览器
  |
  | https://portal.xxx.com
  v
[外部LB / 公网IP / 内网IP]
  |
  v
[Ingress Controller(Nginx)]

────────────────────────────────────────────────────────
                        Kubernetes 集群内部
────────────────────────────────────────────────────────

                ┌─────────────────────────────┐
                │          Ingress规则         │
                │  host: portal.xxx.com       │
                │  /      -> front-service    │
                │  /api/* -> gateway-service  │
                └────────────┬────────────────┘
                             │
              ┌──────────────┴──────────────┐
              │                             │
              v                             v
    ┌──────────────────┐         ┌──────────────────┐
    │   front-service   │         │ gateway-service  │
    │   ClusterIP服务   │         │ ClusterIP服务    │
    └─────────┬────────┘         └─────────┬────────┘
              │                            │
              v                            v
    ┌──────────────────┐         ┌──────────────────┐
    │    front Pod 1    │         │  gateway Pod 1   │
    │  nginx+静态文件    │         └──────────────────┘
    ├──────────────────┤         ┌──────────────────┐
    │    front Pod 2    │         │  gateway Pod 2   │
    │  nginx+静态文件    │         └─────────┬────────┘
    └──────────────────┘                   │
                                           │ 路由到内部服务
                                           v
                             ┌─────────────────────────────┐
                             │        backend service群     │
                             ├─────────────────────────────┤
                             │ user-service  -> user Pod   │
                             │ order-service -> order Pod  │
                             │ auth-service  -> auth Pod   │
                             └─────────────────────────────┘

二、先把每个角色讲明白


1. 前端 Front 是什么?

前端是你用户能看到和点击的页面,例如:

  • 登录页
  • 首页
  • 菜单栏
  • 表格
  • 按钮
  • 图表

你开发时可能写的是:

  • Vue
  • React
  • HTML/CSS/JS

但部署后,一般会被打包成:

  • index.html
  • main.js
  • app.css
  • 图片资源

所以你可以先记住一句:

大多数前端项目,部署后本质上就是静态文件。


2. 后端 Backend 是什么?

后端负责真正的业务逻辑:

  • 用户登录
  • 查询订单
  • 保存表单
  • 权限校验
  • 访问数据库

比如你在页面点"查询用户",前端不是自己知道用户数据,而是调用后端接口:

GET /api/user/list

后端返回 JSON 数据,前端再渲染出来。


3. Gateway 是什么?

Gateway 是"后端统一入口"。

它的作用就像一个总服务台:

  • 前端所有接口都先打到这里
  • 它再决定转给哪个后端服务
  • 还可以统一做 token 校验、限流、日志、灰度等

比如它会判断:

  • /api/user/** -> user-service
  • /api/order/** -> order-service
  • /api/auth/** -> auth-service

所以前端一般不直接调 user-serviceorder-service,而是统一调 gateway


4. Nginx 是什么?

Nginx 非常常见,它通常扮演以下几个角色:

角色 A:静态文件服务器

把前端打包好的 HTML/JS/CSS 返回给浏览器。

角色 B:反向代理

把请求转发给后端。

角色 C:负载均衡

后面有多个实例时,Nginx 可以轮流转发。

角色 D:K8s 的入口控制器

在 K8s 里,常常由 Nginx Ingress Controller 负责把外部请求引入集群内部。


5. Kubernetes(K8s)是什么?

K8s 不是业务代码,它是"容器编排平台"。

它帮你管理这些服务怎么运行:

  • front 怎么部署
  • gateway 怎么部署
  • backend 怎么部署
  • 挂了怎么自动重启
  • 流量怎么负载均衡
  • 怎么滚动发布
  • 怎么扩容

可以理解为:
K8s 是整个系统的"基础设施管理者"。


三、一个请求是怎么一步一步走通的?

这个最关键,我给你拆成两个阶段:


阶段 A:先把页面打开

用户在浏览器输入:

https://portal.xxx.com


第 1 步:浏览器先解析域名

浏览器并不认识 portal.xxx.com,它只认识 IP。

所以要先查:

portal.xxx.com 对应哪个 IP?

这个过程可能来自:

  • 公司 DNS
  • 公网 DNS
  • 你本机的 hosts 文件

比如解析结果:

portal.xxx.com -> 10.10.10.20


第 2 步:请求打到入口层

浏览器向 10.10.10.20 发请求。

这个 IP 通常不是某个具体业务 Pod 的 IP,而是:

  • 负载均衡器 IP
  • Ingress 暴露的 IP
  • Nginx 所在机器 IP

请求先到:

Nginx / Ingress

它是系统的统一入口。


第 3 步:Ingress/Nginx 根据规则分流

比如它有这样的规则:

  • portal.xxx.com/ 路径 -> front-service
  • portal.xxx.com/api/ 路径 -> gateway-service

此时你访问的是 /,所以被转给 front。


第 4 步:Front 返回前端静态资源

front 服务里通常放着:

  • index.html
  • app.js
  • style.css

Nginx 把这些文件返回给浏览器。

浏览器下载这些资源后,就把页面渲染出来了。

这时候你看到的页面,其实只是"页面壳子",很多真实数据还没加载。


阶段 B:页面加载后,再去请求数据

比如你打开用户管理页面,前端 JS 代码会继续发请求:

GET /api/user/list


第 5 步:接口请求再次来到 Ingress/Nginx

请求路径现在是:

/api/user/list

Ingress/Nginx 一看是 /api/ 开头,就知道这是接口请求,不是静态页面请求。

于是把它转给:

gateway-service


第 6 步:Gateway 判断该转给哪个后端

Gateway 根据路由规则判断:

/api/user/** -> user-service

所以这个请求会被转发给:

user-service


第 7 步:Backend 处理业务

user-service 收到请求后:

  • 验证参数
  • 查数据库
  • 组装返回结果

比如查 MySQL 后返回:

[ {"id":1,"name":"张三"}, {"id":2,"name":"李四"} ]


第 8 步:数据沿路返回到浏览器

返回链路是:

user-service -> gateway -> ingress/nginx -> 浏览器

浏览器拿到 JSON 后,前端 JS 把它渲染成表格。

于是你就看到页面上出现了真实的数据。

四、完整请求链路图

我给你画一个更完整的图。

XML 复制代码
【用户访问页面】

浏览器
  |
  | 1. 输入 https://portal.xxx.com
  v
DNS / hosts
  |
  | 2. portal.xxx.com -> 10.10.10.20
  v
Ingress / Nginx
  |
  | 3. 判断 path = /
  v
front-service
  |
  | 4. 转发到某个 front Pod
  v
front Pod (nginx + index.html/js/css)
  |
  | 5. 返回静态资源
  v
浏览器
  |
  | 6. 浏览器执行前端JS
  | 7. 请求 /api/user/list
  v
Ingress / Nginx
  |
  | 8. 判断 path = /api/*
  v
gateway-service
  |
  | 9. 转发到某个 gateway Pod
  v
gateway Pod
  |
  | 10. 路由 /api/user/* -> user-service
  v
user-service
  |
  | 11. 转发到某个 user Pod
  v
user Pod
  |
  | 12. 查询 MySQL / Redis
  v
数据库
  |
  | 13. 返回结果
  v
user Pod -> gateway Pod -> Ingress/Nginx -> 浏览器
  |
  | 14. 前端渲染数据
  v
页面展示最终内容

五、为什么前端看上去"能调接口"?

本质上是因为前端 JS 代码里写了接口地址。

例如:

axios.get('/api/user/list')

这里的 /api/user/list 表示:

  • 还是请求当前域名
  • 但路径走 /api

如果当前页面是:

https://portal.xxx.com

那么浏览器最终发出去的其实是:

https://portal.xxx.com/api/user/list

这样做的好处是:

  • 跟页面同域名
  • 不容易跨域
  • 由 Nginx/Ingress 统一分流

这就是很多项目喜欢这样配的原因:

  • / 走 front
  • /api 走 gateway

六、为什么本地开发经常要配 hosts?

这个点特别重要。


1)hosts 是什么?

你电脑上的一个文件,用来"手工指定域名 -> IP 的映射关系"。

比如你写:

10.10.10.20 portal.xxx.com

意思是:

以后你电脑访问 portal.xxx.com 时,不要去问 DNS 了,直接认为它就是 10.10.10.20


2)为什么要配?

通常有几个原因:

原因 1:测试域名没有正式 DNS

很多测试环境并没有在公司 DNS 或公网 DNS 中配置好。

所以你只能自己本地写。


原因 2:需要访问指定环境

比如:

  • 开发环境入口 IP:10.10.10.20
  • 测试环境入口 IP:10.10.10.30

你可以通过改 hosts,让同一个域名指向不同环境。


原因 3:很多功能必须依赖域名

例如:

  • Cookie 是按域名生效的
  • HTTPS 证书绑定域名
  • 登录回调地址需要固定域名
  • Nginx / Ingress 会根据 Host 做路由

如果你直接访问 IP:

http://10.10.10.20

很多时候会有问题,因为系统不是按 IP 配的,而是按域名配的。


3)为什么不能随便用 IP?

比如 Ingress 规则可能是:

host: portal.xxx.com

只有你请求头里的 Host 是 portal.xxx.com,它才知道该把请求转给 front-service。

如果你直接访问 IP:

http://10.10.10.20

Host 就不是 portal.xxx.com,Ingress 很可能匹配不到规则。

所以:

hosts 的作用是让你本地电脑"假装认识这个域名",并把它指向指定 IP。


七、K8s 里面这些对象到底是什么?

这是你以后看部署配置一定会遇到的。


1)Pod:真正跑容器的地方

Pod 是 K8s 里最小的运行单元。

比如:

  • front Pod
  • gateway Pod
  • user Pod

你可以把 Pod 理解成一个"小运行实例"。

但 Pod 的 IP 不稳定,重建后可能变,所以一般不会直接让别人访问 Pod IP。


2)Deployment:管理一组 Pod

Deployment 用来管理 Pod 的数量和升级。

例如:

  • front 部署 2 个副本
  • gateway 部署 2 个副本
  • user-service 部署 3 个副本

好处:

  • 某个 Pod 挂了,自动补
  • 发版时可以滚动更新
  • 可以随时扩容缩容

例如:

XML 复制代码
front Deployment
  ├─ front Pod 1
  └─ front Pod 2

gateway Deployment
  ├─ gateway Pod 1
  └─ gateway Pod 2

3)Service:给 Pod 提供一个稳定访问入口

因为 Pod IP 会变,所以 K8s 提供 Service。

Service 像一个稳定的门牌号:

  • front-service
  • gateway-service
  • user-service

别人不需要关心 Pod 有几个,也不需要记 Pod IP,只要访问 Service 名字即可。

例如在集群内部:

http://gateway-service http://user-service

K8s 会自动帮你把流量转发到后面的 Pod。


4)Ingress:把外部流量引进来

Ingress 负责定义:

  • 哪个域名
  • 哪个路径
  • 转发到哪个 Service

host: portal.xxx.com paths: / -> front-service:80 /api -> gateway-service:8080

它是 K8s 的"外部入口路由规则"。


八、用 yaml 思维理解部署关系

我不写太复杂,只写小白能看懂的版本。


1)front Deployment

意思是:部署前端服务的 Pod。

XML 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: front
spec:
  replicas: 2
  template:
    spec:
      containers:
        - name: front
          image: nginx-front:1.0

你可以这样理解:

  • 创建一个叫 front 的部署
  • 跑 2 个实例
  • 容器镜像是 nginx-front:1.0
  • 里面放的是前端静态文件

2)front Service

XML 复制代码
apiVersion: v1
kind: Service
metadata:
  name: front-service
spec:
  selector:
    app: front
  ports:
    - port: 80
      targetPort: 80

意思是:

  • 创建一个服务名叫 front-service
  • 它后面关联的是 front Pod
  • 别人访问 front-service:80,就能访问 front Pod

3)gateway Service

XML 复制代码
apiVersion: v1
kind: Service
metadata:
  name: gateway-service
spec:
  selector:
    app: gateway
  ports:
    - port: 8080
      targetPort: 8080

意思是:

  • 创建一个 gateway-service
  • 它指向 gateway Pod
  • 集群内部访问它就能访问网关

4)Ingress 路由规则

复制代码
XML 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: portal-ingress
spec:
  rules:
    - host: portal.xxx.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: front-service
                port:
                  number: 80
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: gateway-service
                port:
                  number: 8080

你把它翻译成人话就是:

  • 如果访问域名 portal.xxx.com
  • 路径是 /,去 front-service
  • 路径是 /api,去 gateway-service

这就是前后端走通的关键连接点。


九、Gateway 怎么找到具体 backend?

在 gateway 里,也会有自己的路由配置。

比如:

XML 复制代码
routes:
  - id: user
    uri: http://user-service:8080
    predicates:
      - Path=/api/user/**
  - id: order
    uri: http://order-service:8080
    predicates:
      - Path=/api/order/**

翻译成人话:

  • /api/user/** 的请求,转发到 user-service
  • /api/order/** 的请求,转发到 order-service

所以 gateway 访问 backend 时,不是靠公网域名,而是靠 K8s Service 名称


十、为什么说 K8s 内部靠 Service 互相调用?

因为 Pod 不稳定,而 Service 稳定。


例子

假设 user-service 后面有 3 个 Pod:

  • user Pod A
  • user Pod B
  • user Pod C

Gateway 只需要访问:

http://user-service:8080

K8s 会自动选择某一个 Pod 来处理:

gateway -> user-service -> user Pod A gateway -> user-service -> user Pod B gateway -> user-service -> user Pod C

这就是服务发现和负载均衡。


十一、Nginx、Ingress、Gateway 容易混,怎么区分?

这个你一定要记住。


1)Ingress

这是 K8s 的"资源对象",用来写路由规则。

你可以理解成"规则配置"。

比如:

  • 什么域名进来
  • 什么路径转哪个 service

2)Ingress Controller(常见是 Nginx)

这是"真正执行 Ingress 规则的程序"。

你可以理解成:

  • Ingress 是配置文件
  • Nginx Ingress Controller 是执行这些配置的代理程序

3)业务 Nginx

有时 front 本身也会是一个 Nginx 容器,用来托管前端静态文件。

所以你在项目里经常会看到两个"nginx"的感觉:

一个是入口 Nginx

负责接收外部请求,按域名/路径分发。

一个是 front 容器里的 Nginx

负责返回前端静态资源。

这两个角色可能是同一种软件,但职责不同。


4)Gateway

这是业务 API 层面的总入口,不只是做简单转发,还会做:

  • token 鉴权
  • 统一异常
  • 灰度
  • 限流
  • 监控埋点

所以它比普通 Nginx 更"懂业务接口"。


十二、你可以这样理解整套系统分层

XML 复制代码
第1层:用户访问层
  浏览器 / App

第2层:域名解析层
  DNS / hosts

第3层:集群入口层
  LB / Ingress / Nginx

第4层:页面和API入口层
  Front / Gateway

第5层:业务服务层
  User Service / Order Service / Auth Service

第6层:数据层
  MySQL / Redis / MQ / ES

十三、最常见的两种部署方式


方式 A:同域名,按路径转发

XML 复制代码
https://portal.xxx.com         -> 前端页面
https://portal.xxx.com/api/*   -> 后端接口

优点

  • 不容易跨域
  • 配置简单
  • 用户只感知一个域名

路由方式

  • / -> front
  • /api/ -> gateway

这是很多后台管理系统最喜欢的方式。


方式 B:前后端不同域名

XML 复制代码
https://portal.xxx.com
https://api.xxx.com

优点

  • 接口边界更清晰
  • 前后端彻底分离
  • 更适合大系统

缺点

  • 可能有跨域问题
  • 需要配置 CORS

十四、为什么前端访问后端有时会报跨域?

浏览器有"同源策略"。

同源要求这三项都相同:

  • 协议相同
  • 域名相同
  • 端口相同

比如页面来自:

https://portal.xxx.com

它去请求:

https://api.xxx.com

域名不同,所以跨域。

这时后端要正确配置跨域响应头,否则浏览器会拦截。

所以很多项目喜欢用:

https://portal.xxx.com/api/*

这样前端和接口同源,不容易出跨域问题。


十五、给你一个"最真实的项目视角"

假设你们项目中有这些组件:

  • front
  • gateway
  • user-backend
  • order-backend
  • nginx ingress
  • mysql
  • redis

那你可以这样理解:


用户访问首页时:

浏览器 -> 域名 -> Ingress/Nginx -> front -> 返回静态页面


页面查用户信息时:

浏览器 -> /api/user/info -> Ingress/Nginx -> gateway -> user-backend -> mysql


页面查订单列表时:

浏览器 -> /api/order/list -> Ingress/Nginx -> gateway -> order-backend -> mysql


登录校验时:

浏览器 -> /api/auth/login -> Ingress/Nginx -> gateway -> auth-backend


gateway 和 backend 的通信方式:

gateway -> user-service gateway -> order-service gateway -> auth-service

都是通过 K8s Service 名称


十六、你以后怎么排查"访问不通"?

这个特别实用,我给你一个排查顺序。


如果页面打不开,按这条链路查:

1. 域名能不能解析?

ping portal.xxx.com nslookup portal.xxx.com

2. 本地 hosts 有没有配错?

检查:

  • 域名写对没
  • IP 对不对

3. Ingress / Nginx 是否正常?

  • 入口 IP 是否正确
  • Ingress 是否有规则
  • Nginx 是否启动正常

4. front-service 是否存在?

kubectl get svc

5. front Pod 是否正常?

kubectl get pods kubectl logs xxx

6. 前端静态文件是否真的打进镜像了?

有时 Nginx 正常,但 index.html 不存在,也会 404。


如果页面打开了,但接口报错,按这条链路查:

1. 浏览器请求的接口地址对不对?

打开 F12 -> Network,看实际请求的是哪个 URL。

2. /api 有没有被转发到 gateway?

看 Ingress 规则。

3. gateway 是否正常?

  • Pod 是否 Running
  • 日志里有没有报错

4. gateway 路由是否正确?

例如:

  • /api/user/** 是否配到了 user-service

5. backend service 是否存在?

kubectl get svc

6. backend pod 是否正常?

kubectl get pods kubectl logs

7. 数据库是否可连接?

很多接口报 500,本质是数据库连接失败。


十七、最适合小白记住的一张脑图

你把下面这段记住,很多问题就能自己想通:

XML 复制代码
1. 浏览器访问的是"域名",不是 Pod
2. 域名要先解析成 IP(DNS 或 hosts)
3. 请求先到 Ingress/Nginx 入口
4. 入口按路径把 / 给 front,把 /api 给 gateway
5. front 返回静态页面
6. 页面里的 JS 再去调用接口
7. gateway 再把接口转给各个 backend
8. backend 查库后返回数据
9. K8s 用 Deployment 管理 Pod,用 Service 提供稳定访问,用 Ingress 接外部流量

十八、最后给你一个"人话版总结"

你可以把整套系统想成一个商场:

  • 域名:商场名字
  • DNS/hosts:导航地图,告诉你商场在哪
  • Ingress/Nginx:商场大门和导购台
  • Front:展示大厅,给你看页面
  • Gateway:总服务台,专门接收办事请求
  • Backend:后面的各业务办公室
  • MySQL/Redis:档案室和缓存柜
  • K8s:整个商场运营管理系统

流程就是:

  1. 你先找到商场地址(域名解析)
  2. 进商场大门(Ingress/Nginx)
  3. 先看到展示大厅(Front)
  4. 真要办业务时去总服务台(Gateway)
  5. 总服务台带你去不同办公室(Backend)
  6. 办公室查档案室(数据库)
  7. 办完再把结果告诉你
相关推荐
To_OC1 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
vipbic1 小时前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy2 小时前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志2 小时前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble3 小时前
c端系统,其实更像一个信息展示平台
前端
李姆斯4 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
戮漠summer4 小时前
Missing Semester 计算机教育中缺失的一课 Lecture 01 Shell
开发语言·后端·scala
weixin_307779134 小时前
Linux下Nginx故障系统化检查Shell脚本
linux·运维·服务器·nginx·自动化
名字还没想好☜5 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司5 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能