API网关的核心功能:路由、负载均衡、限流、熔断、认证鉴权

这一章,我们来聊聊API网关最核心的几个功能。老实说,很多人以为网关就是个「转发器」,这种理解太浅了。我个人习惯把网关看作是整个微服务架构的「看门人」——它不光要认路,还得控制流量、保护后端,甚至能在系统快撑不住的时候主动「拉闸」。

你想想看,如果没有网关,每个微服务都得自己去处理鉴权、限流、熔断这些东西,那得多乱?我过去参与的一个项目,早期没上网关,结果每个服务都得自己配一套限流逻辑,改起来简直是噩梦。后来统一用网关兜底,世界一下就清净了。

咱们一个一个说。

路由:网关最基础的「导航」能力

路由说白了,就是把客户端发来的请求,按规则转发到正确的后端服务上。它是网关的第一道工序。

路由配置通常包含几个要素:

  • 请求路径:比如 /api/users/** 转到用户服务
  • 请求方法:GET、POST、PUT、DELETE 可以走不同路由
  • 请求头/参数:根据 Header 或 Query String 做条件路由
  • 目标地址:后端服务的实际 URL

举个例子,我用 Spring Cloud Gateway 时,路由配置大概是这样的:

spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/users/**
          filters:
            - StripPrefix=1
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/api/orders/**
          filters:
            - StripPrefix=1
小技巧:路由匹配规则尽量精确,不要一股脑用 /** 兜底。我在项目中见过因为路由规则写得太宽,导致本该走到 A 服务的请求跑到了 B 服务,排查了半天才发现是路径优先级的问题。

负载均衡:把流量均匀分给后端实例

当一个服务部署了多个实例,网关就需要做负载均衡。常见的算法有:轮询、最少连接、IP 哈希、一致性哈希。

我个人最常用的是轮询结合健康检查。为什么?简单可靠。有个项目早期用了最少连接算法,结果因为某些请求处理时间特别长,反而让连接数分布不均匀,最后还是切回了轮询。

来看看一张负载均衡的流程图:

负载均衡核心流程 客户端请求 API网关 - 负载均衡器 实例 1 (可用) 实例 2 (可用) 实例 3 (熔断) 健康检查 + 轮询策略,自动规避故障实例
经验之谈:我建议给负载均衡策略加一个「权重」参数。不同机器配置不一样,高配机器权重设高一点,低配设低一点,这样流量分配更合理。

限流:防止后端被「流量洪峰」冲垮

限流,就是控制单位时间内通过的请求数量。你想想看,电商大促那几秒钟,流量可能是平时的几百倍。如果没有限流,后端服务分分钟被打挂。

常见的限流算法有四种:

算法 特点 适用场景
固定窗口 简单,但窗口边界有突刺 小规模、对精度要求不高
滑动窗口 更平滑,精度更高 一般生产环境推荐
令牌桶 允许短时突发流量 需要容忍突发请求的场景
漏桶 请求均匀流出,不能突发 对流量平滑度要求极高的场景

我曾经在给一个金融项目做网关时,用了固定窗口算法,结果业务方反馈说「明明没超限,为什么被拦了?」一查才发现,固定窗口在临界点会出现流量翻倍的「坑」,换成滑动窗口之后就正常了。

用 Nginx 加 Lua 做过限流的配置示例:

-- 基于令牌桶的限流
local limit_req = require "resty.limit.req"
local lim, err = limit_req.new("my_limit_store", 100, 50)
-- 每秒 100 个令牌,最多突发 50 个

local delay, err = lim:incoming(ngx.var.uri, true)
if not delay then
    if err == "rejected" then
        ngx.exit(ngx.HTTP_SERVICE_UNAVAILABLE)
    end
    return
end

if delay >= 0.001 then
    ngx.sleep(delay)
end

熔断:主动「断臂求生」

熔断和限流是两码事。限流是保护后端不被冲垮,而熔断是当后端已经出问题的时候,网关主动放弃调用,避免连锁反应。

我个人习惯用三个状态来描述熔断器:

  • 关闭:正常状态,请求正常通过
  • 打开:失败率达到阈值,直接拒绝请求,快速失败
  • 半开:过一段时间后,放少量请求试探服务是否恢复
注意:熔断的阈值设置很讲究。设得太敏感,正常抖动就熔断了;设得太宽松,又起不到保护作用。我曾经历过一次因为熔断阈值设得太高,导致数据库被拖垮,进而引发服务雪崩的教训。

认证鉴权:把不速之客拦在外面

认证是「你是谁」,鉴权是「你能干什么」。网关在这一层做统一控制,比每个服务自己搞要高效得多。

常见的认证方式:

  • JWT(JSON Web ):无状态,适合分布式架构
  • OAuth2:授权协议,常用于第三方登录
  • :简单粗暴,适合内部服务调用
  • Basic Auth:最基础,但不推荐用在生产环境

举个例子,我用 JWT 做认证时,网关层做的事很简单——校验 签名、检查有效期、把解析出的用户信息塞到请求头里转发给后端。后端服务不用再关心「这 是谁发的」,只需要信任网关传过来的头信息就行。

嗯,这里要注意一件事:网关的鉴权做不到「100% 由网关兜底」。有些更细粒度的权限(比如「用户只能看自己的订单」)还是需要后端自己判断。网关做的是「粗粒度」的认证鉴权,比如「这个用户有没有访问订单服务的权限」。

最佳实践:我习惯把认证和鉴权分开。认证走网关统一处理,鉴权则用「策略即代码」的方式在网关层做一部分,剩下的交给后端。这样既减轻了后端负担,又保留了灵活性。

好啦,这一章的内容就是这样。API 网关的这几个核心功能,说白了就是一套组合拳:路由让你能找到路,负载均衡让你走路不挤,限流让路不堵,熔断保证路坏了不连累其他路,认证鉴权则是给这条路上了把锁。理解它们之间的关系,比死记硬背配置命令重要得多。