微服务请求全链路解析:从前端到微服务,一次看懂 Nginx、Nacos、网关与 MVC 拦截器到底干了啥
一、引言
在微服务架构大行其道的今天,我们前端轻轻点下一个查询按钮、提交一次表单,背后早已不是单体应用里简单的 “接口调用”。一个看似普通的 HTTP 请求,会穿过网关、认证中心、注册中心,再在多个微服务之间来回流转、RPC 通信、数据聚合,最后才原路返回,展现在页面上。
很多开发者只知道 “调用服务”“加个 Feign”,却不清楚请求从浏览器发出那一刻起,到底走过了哪些组件、经历了哪些校验、发生了几次网络交互、遇到异常又会怎样流转。
本文就以一次真实业务请求为例,从头到尾梳理一遍:前端发起请求 → 进入后端微服务体系 → 内部调用其他微服务 → 最终返回结果的全链路过程,带你看清一次微服务请求的完整生命周期。
本文以learning-service向course-service转发请求为例。
二、发起请求
2.1 前端构建请求
- 前端(JS/Android/iOS)组装 HTTP 请求:
- 请求行:
GET /api/learning/lessons?userId=1001 HTTP/1.1(请求方法、路径、协议版本); - 请求头:
Host: www.tianji.com(目标域名)、Content-Type: application/json(数据格式)、Cookie: token=xxx(身份凭证)、User-Agent: Chrome/120(客户端信息)等; - 请求体:GET 请求无体,POST/PUT 会携带 JSON / 表单数据;
- 请求行:
- 前端框架(如 Axios)封装请求,处理跨域(CORS)预检(OPTIONS 请求)(如果是跨域场景)。
2.2 客户端 DNS 解析(网络基础)
- 前端发起请求时,首先解析域名
www.tianji.com为 IP 地址:- 查本地 DNS 缓存(浏览器 / 操作系统缓存)→ 命中则直接用;
- 未命中则请求本地 DNS 服务器(运营商 / 公司内网 DNS)→ 递归查询根 DNS→顶级 DNS→权威 DNS,最终返回 Nginx 服务器的公网 IP(如
192.168.150.101);
- 解析完成后,客户端知道要把请求发送到这个 IP 对应的服务器。
2.3 建立 TCP 连接(三次握手)
- 客户端与 Nginx 服务器的 80/443 端口建立 TCP 连接(HTTP 基于 TCP):
- 客户端发送
SYN包,请求建立连接; - Nginx 回复
SYN+ACK包,确认连接请求; - 客户端回复
ACK包,TCP 连接建立(三次握手完成);
- 客户端发送
- HTTPS 场景:还会额外进行 TLS 握手(协商加密算法、验证证书、生成会话密钥),将 HTTP 加密为 HTTPS。
2.4 发送 HTTP 请求
- 客户端通过已建立的 TCP 连接,将组装好的 HTTP 请求数据包发送给 Nginx 服务器。
三、反向代理
3.1 Nginx 接收请求
- Nginx 的 worker 进程监听 80/443 端口,接收到客户端的 HTTP 请求数据包;
- Nginx 解析请求头(如 Host、Path),匹配
nginx.conf中的location规则。
3.2 反向代理转发
- Nginx 中配置了对
/api/路径的转发规则 - Nginx 向网关集群(Gateway)发起新的 HTTP 请求,转发客户端的请求内容(路径、参数、请求头)。
3.3 负载均衡
- 如果网关是集群部署,Nginx 会通过内置负载均衡策略(如轮询、加权轮询、ip_hash)选择一个网关实例转发请求。
四、网关
4.1 网关接收请求
- Spring Cloud Gateway 监听 8080 端口,接收 Nginx 转发的请求;
- 网关的核心处理器接收请求,开始执行「网关过滤器链」。
4.2 前置过滤器执行(全局过滤器 / 路由过滤器)
- 身份认证:过滤器解析请求头中的
token(如 JWT),校验签名、有效期,解析出 userId(如 1001),未通过则直接返回 401; - 权限校验:校验 userId 是否有访问
/api/learning/lessons接口的权限,未通过返回 403; - 限流熔断:检查该接口 / IP / 用户的 QPS 是否超限,超限则返回 429;
- 请求日志:记录请求的 IP、路径、参数、时间等;
- 路径重写:比如将
/api/learning/lessons重写为/learning/lessons(适配微服务接口路径)。
4.3 路由匹配与服务发现
- 网关根据请求路径匹配路由规则(配置在 Nacos / 本地配置)
- 网关通过 Nacos 注册中心获取
learning-service的所有可用实例。
4.4 负载均衡(Ribbon/Nacos LoadBalancer)
- 网关内置的负载均衡器(如 Spring Cloud LoadBalancer)从可用实例列表中选择一个(如轮询选第一个)。
4.5 转发请求到微服务
- 网关将请求转发到选中的微服务 实例,携带解析后的 userId、权限信息等。
五、业务处理
5.1 微服务接收请求
learning-service的 Tomcat 监听 8090 端口,接收 Gateway 转发的请求;- Spring MVC 的
DispatcherServlet接管请求,准备执行 MVC 拦截器。
5.2 执行 MVC 拦截器(核心:上下文存储)
- 核心作用:将
userId存入ThreadLocal,后续 Service/DAO 层可直接获取(无需层层传参); - 若请求异常(如参数错误),
afterCompletion仍会执行:UserContext.removeUser()(清理 ThreadLocal,避免数据串扰)。
5.3 Controller 接收并处理请求
- 匹配
LearningLessonController的接口,然后进行参数校验
5.4 Service 层处理(含服务转发 / 跨服务调用)
六、跨服务调用
6.1 Feign 客户端定义
learning-service 中需定义 course-service 的 Feign 客户端接口(声明要调用的方法)
// learning-service 中的 Feign 客户端
@FeignClient(name = "course-service") // 指向 Nacos 中的服务名
public interface CourseClient {
// 声明要调用的 course-service 接口
@GetMapping("/course/name/{courseId}")
String getCourseNameById(@PathVariable("courseId") Long courseId);
// 批量查询(更高效)
@PostMapping("/course/names")
Map<Long, String> getCourseNamesByIds(@RequestBody List<Long> courseIds);
}
@FeignClient(name = "course-service"):指定要调用的服务名(必须和 Nacos 中course-service的服务名一致)。
6.2 Feign 结合 Nacos 做服务发现
当 learning-service 调用 courseClient.getCourseNamesByIds([101, 102]) 时,Feign 会触发以下操作:
- 查询 Nacos 获取 course-service 实例:
- Feign 内置的
LoadBalancerClient向 Nacos 发送请求:GET http://192.168.150.101:8848/nacos/v1/ns/instance/list?serviceName=course-service; - Nacos 返回
course-service的健康实例列表(如192.168.150.104:8091);
- Feign 内置的
- 负载均衡选择实例:
- Feign 从实例列表中按策略(轮询 / 加权)选择一个实例(如
192.168.150.104:8091);
- Feign 从实例列表中按策略(轮询 / 加权)选择一个实例(如
- 组装 HTTP 请求并发送:
- Feign 自动将接口调用转换为 HTTP 请求:
POST http://192.168.150.104:8091/course/names,请求体为[101, 102]; - 透传必要的请求头(如 Token、TraceId),保证跨服务调用的身份和链路追踪。
- Feign 自动将接口调用转换为 HTTP 请求:
6.3 course-service 处理请求
course-service的 Tomcat 接收 Feign 发送的 HTTP 请求;- course-service 的 MVC 拦截器执行(读取
USER_INFO并存入 ThreadLocal) - Controller 层匹配
/course/names接口,调用 Service 层查询课程名称(从数据库 / 缓存获取); - 返回响应,learning-service 接收响应并处理
七、Gateway的过滤器vsMVC拦截器
7.1 顺序
一个请求从前端到达微服务的完整链路中,先经过网关(Gateway)的过滤器链,后经过微服务内的 MVC 拦截器—— 网关过滤器链是 “入口第一道关卡”,MVC 拦截器是 “微服务内部最后一道关卡”。
7.2 范围
微服务间通过 Feign 转发请求(如 learning-service 调用 course-service)时,默认不会经过 Gateway 网关的过滤器链;但如果是前端请求直接转发(如 Gateway 路由转发到微服务),则会完整执行网关过滤器链。
| 转发场景 | 是否经过网关过滤器链 | 核心原因 | 适用场景 |
|---|---|---|---|
| 微服务间 Feign 直接调用 | ❌ 不经过 | 内部调用,绕过网关 | 服务间高频调用(追求性能) |
| Feign 调用网关再转发 | ✅ 完整经过 | 请求先到网关,触发过滤器链 | 需要统一管控服务间调用规则 |
| Gateway 路由转发外部请求 | ✅ 完整经过 | 网关是外部请求的唯一入口,必须统一管控 | 前端→微服务的所有入口请求 |
7.3 对比
| 维度 | MVC 拦截器(微服务内) | Gateway 过滤器(网关层) |
|---|---|---|
| 执行范围 | 仅当前微服务的 HTTP 请求 | 所有经过网关的外部请求 |
| 拦截对象 | 微服务内的 Controller 方法 | 网关的路由转发请求 |
| 执行时机 | 请求到达微服务后,匹配 Controller 前 | 请求到达网关后,转发到微服务前 |
| 核心作用 | 微服务内的业务拦截(如权限细化、日志) | 全局管控(认证、限流、跨域) |
| 内部方法调用 | 不触发 | 不涉及(仅处理 HTTP 请求) |
八、结果返回
service层处理完业务逻辑之后
8.1 DAO 层 / 数据库交互
8.1 learning-service 组装响应
8.2 反向执行过滤器 / 拦截器
- learning-service 的 MVC 拦截器执行
afterCompletion:UserContext.removeUser()(清理 ThreadLocal); - Gateway 执行后置过滤器:Gzip 压缩响应、记录响应日志、添加跨域头(
Access-Control-Allow-Origin: *); - Nginx 接收压缩后的响应 → 加密后通过 TLS 连接回传给前端。
8.3 前端接收并渲染
- 浏览器解密响应 → 解析 JSON 数据 → 渲染课程列表到页面;
- TCP 连接处理:HTTP/1.1 默认为长连接,保持复用;若为短连接,执行 TCP 四次挥手关闭连接。
九、Nocas
在一个请求从客户端到微服务的完整链路中,Nacos 核心承担「服务注册中心」和「配置中心」两大角色,贯穿「服务发现→请求转发→配置加载」全流程。
在任何请求到达前,Nacos 已经完成了「微服务注册」和「配置推送」,这是请求能正确转发的基础
9.1 微服务注册
微服务启动时,向 Nacos 注册自身(核心)
当 learning-service、tj-auth、tj-course 等微服务启动时,会主动向 Nacos 注册元数据,流程如下:learning-service 启动 → 读取 application.yml 中的 Nacos 地址 → 向 Nacos 发送注册请求 → Nacos 存储服务实例信息
- 微服务侧操作:微服务通过
spring-cloud-starter-alibaba-nacos-discovery依赖,自动触发注册逻辑,向 Nacos 提交以下信息:- 服务名:
learning-service(spring.application.name配置); - 实例信息:IP(如
192.168.150.102)、端口(8090)、健康检查地址(/actuator/health); - 附加信息:分组(DEFAULT_GROUP)、命名空间(public)、权重(1.0)。
- 服务名:
- Nacos 侧操作:
- 接收注册请求,将
learning-service的实例信息存入内置数据库(Derby/MySQL); - 维护「服务 - 实例」映射表(如
learning-service → [192.168.150.102:8090, 192.168.150.103:8090]); - 启动健康检查:每隔 5 秒向微服务的
/actuator/health发送请求,标记实例状态(健康 / 不健康),剔除不健康实例。
- 接收注册请求,将
9.2 拉取配置
微服务 / Gateway 从 Nacos 拉取配置(可选但常用)
如果微服务 / Gateway 的配置(如数据库连接、接口限流规则)托管在 Nacos,启动时会从 Nacos 拉取配置:
- Gateway 侧:拉取路由规则(如
/learning/lessons/**转发到learning-service)、限流规则; - learning-service 侧:拉取数据库连接信息、Feign 调用超时时间等;
- Nacos 侧操作:
- 根据微服务的
spring.application.name+ 命名空间,匹配对应的配置集; - 将配置推送给微服务,并建立「配置监听」(配置修改时,Nacos 主动推送最新配置给微服务,无需重启)。
- 根据微服务的
9.3 返回实例
Gateway 基于 Nacos 返回的实例做负载均衡
Gateway 内置的 Spring Cloud LoadBalancer(或 Ribbon):
- 从 Nacos 返回的实例列表中,按策略(轮询 / 加权轮询)选择一个实例(如
192.168.150.102:8090); - 将原始请求转发到该实例。
更多推荐




所有评论(0)