一、引言

在微服务架构大行其道的今天,我们前端轻轻点下一个查询按钮、提交一次表单,背后早已不是单体应用里简单的 “接口调用”。一个看似普通的 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 从实例列表中按策略(轮询 / 加权)选择一个实例(如 192.168.150.104:8091);
  • 组装 HTTP 请求并发送
    • Feign 自动将接口调用转换为 HTTP 请求:POST http://192.168.150.104:8091/course/names,请求体为 [101, 102]
    • 透传必要的请求头(如 Token、TraceId),保证跨服务调用的身份和链路追踪。

6.3 course-service 处理请求

  1. course-service 的 Tomcat 接收 Feign 发送的 HTTP 请求;
  2. course-service 的 MVC 拦截器执行(读取 USER_INFO 并存入 ThreadLocal)
  3. Controller 层匹配 /course/names 接口,调用 Service 层查询课程名称(从数据库 / 缓存获取);
  4. 返回响应,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 拦截器执行 afterCompletionUserContext.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-servicetj-authtj-course 等微服务启动时,会主动向 Nacos 注册元数据,流程如下:learning-service 启动 → 读取 application.yml 中的 Nacos 地址 → 向 Nacos 发送注册请求 → Nacos 存储服务实例信息

  • 微服务侧操作:微服务通过 spring-cloud-starter-alibaba-nacos-discovery 依赖,自动触发注册逻辑,向 Nacos 提交以下信息:
    • 服务名:learning-servicespring.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);
  • 将原始请求转发到该实例。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐