2、核心功能解析:路由转发、负载均衡、限流熔断、身份认证

好,咱们进入正题。API网关这东西,说白了就是个「交通枢纽」。你想想看,所有外部请求要进到你的PaaS平台,都得先过它这一关。那它到底干了哪些活?我把它拆成四个核心功能来讲:路由转发、负载均衡、限流熔断、身份认证。这四个功能,缺一个,你的网关就可能变成「瓶颈」而不是「枢纽」。

2.1 路由转发:请求该去哪儿?

路由转发是网关最基础的能力。客户端发来一个请求,比如 /api/v1/users/123,网关得知道这个请求该转发给哪个后端服务。

我个人习惯把路由规则设计成「前缀匹配 + 精确匹配」的组合。举个例子:

# 路由配置示例
routes:
  - id: user-service
    uri: http://user-svc:8080
    predicates:
      - Path=/api/v1/users/**
  - id: order-service
    uri: http://order-svc:8081
    predicates:
      - Path=/api/v1/orders/**
  - id: payment-service
    uri: http://payment-svc:8082
    predicates:
      - Path=/api/v1/payments/**

这里要注意一个坑。我曾经在一个项目里,把路由规则写成了 /api/v1/** 这种通配符,结果所有请求都匹配到了同一个服务。嗯,这其实是个典型的「路由冲突」问题。我的建议是:精确路径优先,通配符路径兜底。你可以在路由表里加一个优先级字段,数值越小优先级越高。

小技巧: 路由转发时,别忘了做路径重写。比如前端请求 /api/v1/users/123,后端服务可能只认 /users/123。用 RewritePath 过滤器就能搞定。

2.2 负载均衡:别让一台机器累死

路由转发只是第一步。当你的用户服务部署了3个实例,网关该把请求发给谁?这就是负载均衡要解决的问题。

常见的策略有几种:

  • 轮询(Round Robin):按顺序轮流分发。简单,但容易忽略后端实例的实际负载。
  • 最少连接(Least Connections):谁当前处理的请求少,就发给谁。适合长连接场景。
  • 一致性哈希(Consistent Hash):根据请求的某个特征(比如用户ID)做哈希,保证同一个用户的请求始终落到同一台机器。这对缓存友好。

我在项目中遇到过一个问题:用轮询策略时,某台机器因为GC停顿,响应变慢,但网关还是继续给它发请求。结果那台机器直接被打挂了。后来我换成了「自适应负载均衡」,网关会实时收集后端实例的响应时间和错误率,动态调整权重。说白了,就是谁表现好,多给它点流量。

核心要点: 负载均衡不是简单的「分派任务」,而是要结合健康检查。网关应该定期探测后端实例是否存活,一旦发现异常,立即摘除流量。

2.3 限流熔断:保护你的系统不被冲垮

这是网关最「救命」的功能。你想想看,双十一大促,流量突然暴涨10倍,如果没有限流熔断,你的PaaS平台可能瞬间崩溃。

限流,说白了就是控制流量进入的速度。常用的算法有:

算法 原理 适用场景
令牌桶 以固定速率生成令牌,请求拿到令牌才能通过 允许突发流量,但总体速率可控
漏桶 请求先进入桶里,以固定速率流出 平滑流量,适合保护下游
滑动窗口 统计时间窗口内的请求数,超过阈值则拒绝 精确控制,但内存开销稍大

我个人偏爱令牌桶算法。为什么?因为它允许一定的突发流量,比如用户突然刷新页面,不会立刻被限住。但要注意,令牌桶的「桶大小」和「生成速率」要调优。我曾经把桶设得太大,结果限流形同虚设。

熔断呢?它和限流是两回事。限流是「主动控制」,熔断是「被动保护」。当某个后端服务连续出错,比如5秒内错误率达到50%,网关就该熔断了——直接返回一个降级响应,而不是继续把请求发过去。这就像电路里的保险丝,电流过大就断开,防止烧毁整个系统。

避坑指南: 我曾经犯过一个错:熔断后没有设置「半开状态」。结果服务恢复了,网关还一直熔断着,导致业务中断了半小时。正确的做法是:熔断后进入「半开状态」,允许少量请求试探,如果成功则关闭熔断,否则继续熔断。

2.4 身份认证:谁在敲门?

最后一个核心功能,也是安全的第一道防线。网关必须验证每个请求的「身份」。常见的做法是JWT(JSON Web Token)。

流程大概是这样的:

  1. 客户端登录,认证服务颁发一个JWT令牌。
  2. 客户端每次请求,都在Header里带上 Authorization: Bearer <token>
  3. 网关解析JWT,验证签名和有效期,提取用户信息。
  4. 如果验证通过,把用户信息通过Header传给后端服务。

代码示例(伪代码):

// 网关JWT验证过滤器
public class JwtAuthFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getRequest().getHeaders()
            .getFirst("Authorization");
        if (token == null || !token.startsWith("Bearer ")) {
            // 返回401
            return unauthorized(exchange);
        }
        try {
            Claims claims = Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(token.substring(7))
                .getBody();
            // 把用户ID塞进请求头
            exchange.getRequest().mutate()
                .header("X-User-Id", claims.get("userId").toString());
        } catch (Exception e) {
            return unauthorized(exchange);
        }
        return chain.filter(exchange);
    }
}

这里有个细节:JWT的密钥要定期轮换。我见过一个项目,密钥用了两年没换,结果泄露了,整个平台的用户数据都被爬了。嗯,血的教训。

进阶建议: 对于内部服务之间的调用,可以用「服务间认证」——每个服务分配一个API Key,网关验证Key的有效性。这样即使JWT泄露,外部攻击者也拿不到内部API Key。

小结

这四个功能,路由转发是「指路」,负载均衡是「分派」,限流熔断是「保护」,身份认证是「守门」。它们共同构成了API网关的骨架。你想想看,如果没有它们,你的PaaS平台就像一栋没有门卫、没有电梯调度、没有消防系统的大楼——乱成一团。

下一章,我会深入讲「限流熔断」的实战配置,包括如何用Sentinel或Resilience4j实现精细化的流量控制。到时候咱们再细聊。