微服务核心02:API 网关

从流量入口、统一治理和业务边界三个角度,判断 API 网关应该管什么,以及哪些逻辑不该塞进网关。

字数 2178 阅读时长 ≈ 7 分钟 2026-6-2 2026-7-12
微服务核心02:API 网关

API 网关解决什么问题

API 网关解决的不是”把请求转发到某个服务”这么简单。真正需要网关的时候,系统通常已经遇到一个问题:服务拆开以后,外部调用方不应该知道内部有多少服务、服务怎么命名、实例怎么扩缩容、鉴权和限流规则分别写在哪里。

网关就是微服务体系的入口边界。它把外部流量先收拢起来,再把路由、认证、限流、灰度、观测这些入口能力统一处理掉。

更深入一点,网关不是”统一 Controller”,而是一条入口过滤链。一次请求进来以后,通常会经历路由匹配、身份校验、权限判断、限流、协议或字段转换、后端转发、响应处理、指标记录几个阶段。每个阶段都要尽量无状态、可观测、可回滚,因为网关位于所有流量前面,任何复杂逻辑都会被流量放大。

场景:入口混乱会怎么发生

一个很典型的演进场景是:刚拆微服务时,前端直接调用户服务、订单服务、支付服务、优惠券服务。短期看少了一层转发,长期会出现一堆问题:

  • 前端需要知道太多后端服务地址
  • 每个服务都要重复写登录校验和签名校验
  • 限流规则分散在各个服务里,很难统一保护入口
  • 内部服务改名、拆分、迁移时,外部调用方也被迫跟着改
  • 出问题时,只能到各个服务里分别看日志

网关的价值在这里:外部只面对一个入口,内部服务可以继续演进。调用方不关心订单服务有几个实例,也不关心某个接口现在由 order-service-v2 处理还是灰度到新版本。

网关的两类核心职责

类别能力说明
入口基础能力路由转发根据域名、路径、Header、灰度规则转到不同后端
认证鉴权校验登录态、Token、签名、租户信息
限流防刷按 IP、用户、接口、租户、应用维度限制入口流量
协议适配把外部 HTTP 请求转成内部 HTTP、RPC 或统一契约
统一观测记录入口耗时、状态码、调用方、traceId
灰度发布按用户、比例、Header 或租户切流
轻量聚合能力BFF 聚合移动端页面需要多个服务数据时做简单聚合
字段裁剪根据端侧需要裁剪返回字段

但这个边界要非常克制。网关不应该理解复杂业务流程,不应该直接操作订单状态,也不应该把库存、支付、优惠券这些领域规则写进去。

网关过滤链

网关执行流程可以先看这张过滤链图。它比简单的”客户端到服务端”更重要的一点,是把失败拦截、灰度选择、BFF 适配和领域服务边界放在同一条入口链路里:

API 网关过滤链

这里最关键的不是”能不能转发”,而是顺序和失败语义。认证失败应该在路由到业务服务前结束;限流失败应该返回明确的入口错误;后端超时要区分是网关连接失败、业务服务超时,还是业务服务返回了错误。否则排查时所有问题都会变成一个笼统的 5xx。

网关还要处理超时预算。比如入口超时是 1500ms,网关自己不能把后端转发超时也设成 1500ms,因为还要留出网络、重试、响应包装和客户端等待的时间。网关层通常应该比客户端超时短,比后端单次调用预算略长,避免两端同时等待到最后一刻。

过滤链的顺序会影响安全和成本

网关不是把所有能力随便串起来。过滤链顺序错了,会直接影响安全性和资源成本。

基础校验要尽量靠前,避免大 body、非法 header、未知路径消耗后端资源。认证要早于业务路由里的敏感逻辑,鉴权要早于转发。限流放在认证之后,才能按用户、租户、应用做精确维度;但一些防刷规则也可以在认证前按 IP 粗限流。

灰度选择要在转发前完成,并且要进入 trace 和访问日志。否则某次请求到底命中了 v1 还是 v2,事故时只能猜。

如果网关支持插件化,还要限制插件能力。插件能不能访问外部网络?能不能读写请求 body?失败时是 fail-open 还是 fail-closed?认证插件失败通常要 fail-closed,观测插件失败可以 fail-open。不同插件的失败语义不能一刀切。

常见误区:网关变成大单体

很多团队一开始接网关,是为了统一入口。用着用着,大家发现”放在网关里改得快”,于是各种逻辑都往里面塞:

  • 特殊活动的价格判断
  • 某个业务线的字段补齐
  • 老接口兼容新接口的复杂转换
  • 临时绕开后端服务的查询逻辑

短期看很方便,长期会把网关写成新的大单体。它既要承接所有流量,又包含各种业务分支,一旦发布出问题,影响面比普通服务大得多。

判断一段逻辑该不该放网关,通常问三个问题:

  1. 这段逻辑是否和具体业务状态强相关?
  2. 这段逻辑是否需要访问业务数据库?
  3. 这段逻辑失败后,是否会改变业务结果?

如果答案是”是”,它大概率不该放在网关。

项目实践:网关、BFF 和业务服务分层

一个比较稳的落地方式是先把规则分层:

层级职责例子
API Gateway入口治理认证、限流、路由、灰度、入口日志
BFF端侧适配数据聚合、字段裁剪、展示适配
Domain Service业务规则订单、库存、支付等领域逻辑

不是每个项目都必须单独做 BFF,但”入口治理”和”业务编排”最好不要混在同一个网关里。否则网关既要扛住所有流量,又要频繁跟业务需求一起发布,风险会越来越高。

配置上也要避免散乱。路由规则、灰度规则、限流规则最好能被版本化,并且能快速回滚:

routes:
  - id: order-api
    path: /api/orders/**
    service: order-service
    timeoutMs: 800
    rateLimit:
      key: userId
      qps: 20

这段配置表达的是治理意图:入口先有明确路由,再有超时和限流,不要让一次外部请求无限制地占住内部资源。

网关设计里还有两个容易被忽略的工程点。

第一个是路由优先级/api/orders/**/api/orders/internal/** 如果都存在,匹配顺序必须明确,否则内部接口可能被外部规则误放行。

第二个是错误码规范。认证失败、权限不足、限流、路由不存在、后端超时、后端业务失败,应该能从状态码和错误码里区分出来,不然网关会把排查信息抹平。

如果团队规模稍大,更建议把网关规则当成配置资产管理:谁申请路由、谁审批、什么时候上线、影响哪些客户端、如何回滚,都要留下记录。网关是入口,不是临时需求垃圾桶。

排查路径:先看入口证据

网关出问题时,用户看到的通常是”接口失败”或”页面打不开”。这时不要直接跳到业务服务里猜,先看入口层:

  1. 请求有没有到达网关
  2. 返回码是网关产生的,还是后端服务透传的
  3. 是否命中认证失败、限流、路由不存在、超时
  4. 上游调用方、租户、用户维度是否集中异常
  5. traceId 是否从网关传到了后端服务

如果网关日志里显示请求根本没有转发,问题就在入口规则、认证、限流或路由。如果网关已经转发,后端耗时异常,再顺着 traceId 往下看。

具体看日志时,网关至少要打印这些字段:routeId、调用方应用、用户或租户标识、限流 key、上游服务、后端状态码、入口耗时、后端耗时、traceId。没有这些字段,网关日志只能证明”有请求来过”,不能证明它被哪条规则处理过。