3. 网关扩展点概览:常见的扩展机制

做内部开发者平台,网关就是那个“守门人”。但它不是死板的铁门,更像一个乐高底座——你可以往上插各种功能模块。我今天聊的就是这些“插口”长什么样,什么时候用哪个。

我自己刚接触网关扩展时,也被一堆概念搞晕过:插件、过滤器、断言、拦截器……说白了,它们都是把自定义逻辑塞进请求处理流程的手段。但各有各的擅长领域。

网关扩展点架构 API 网关核心 客户端请求 后端服务 插件 (Plugin) 认证、限流、日志、协议转换 过滤器 (Filter) 请求/响应处理链、内容修改、校验 断言 (Predicate) 路由匹配、条件分发、灰度策略 拦截器 (Interceptor) 前后处理、上下文传递、重试 四种扩展点可混用,但注意执行顺序与性能开销

3.1 插件:最常用的“搭积木”方式

插件机制,说白了就是在网关启动时加载一段独立模块。我见过的大部分团队,都是从插件开始接触网关扩展的。打个比方,网关核心就一个空架子,插件像USB设备——插上就能干活,拔掉也没事。

我在项目中用过最常见的插件类型:

  • 认证插件:OAuth2、JWT验证、LDAP对接
  • 限流插件:基于Redis的令牌桶、漏桶算法
  • 日志插件:请求/响应日志,用于审计和调试
  • 协议转换插件:比如将HTTP格式转为gRPC或Dubbo协议
核心原则:插件与网关核心解耦,可单独升级。但注意插件数量越多,启动和热加载可能变慢。

曾有一次线上事故,某团队同时接了15个插件,其中一个日志插件有内存泄露。排查时靠逐个禁用插件才找到元凶。所以后来我定了一条规矩:生产环境插件不超过8个,超过就必须做性能压测。

3.2 过滤器:管好“请求/响应”的链

过滤器与插件有点像,但更“线性”。它们按顺序组成一条链,请求进门是顺序,响应出门是逆序。Spring Cloud Gateway里的过滤器就是典型。

我平时把过滤器分为三类:

  • 前置过滤器:在路由之前做校验、添加Header、修改请求体。比如给所有请求添加一个X-Trace-Id。
  • 路由过滤器:与具体路由绑定,比如只对某个路径的请求做重写。我在做版本灰度时常用这个。
  • 后置过滤器:处理响应内容,比如压缩、加密、统一包装。
// 一个简单的后置过滤器示例(Kotlin风格)
filter {
  order(Ordered.LOWEST_PRECEDENCE - 1)
  filter(exchange, chain) {
    val response = chain.filter(exchange).then(
      Mono.fromRunnable {
        val original = exchange.response.bufferFactory().wrap("{}".toByteArray())
        // 这里做响应体修改
      }
    )
    response
  }
}
过滤器顺序非常关键。我曾经把“添加CORS头”的过滤器放在了安全校验之后,结果跨域请求在预检阶段就被拦截了……浪费了半天排查。

3.3 断言:网关的路由“决策者”

断言(Predicate)是网关中用来决定“这个请求走哪条路”的东东。它不修改请求,只返回true/false。你想想看,一个内部平台可能有几十个微服务,多版本共存、灰度发布、A/B测试,全靠断言来分流。

常见的内置断言:

断言类型 作用 举例
Path 匹配请求路径 /api/v1/**
Header 要求请求头存在且值匹配 X-Version=v2
Query 要求查询参数匹配 ?env=staging
Cookie 匹配Cookie值 gray=1
Weight 按权重随机路由(灰度) group1=80, group2=20
注意:断言最好保持幂等(相同输入始终相同输出)。我曾经写了一个依赖当前时间的断言用于“时段路由”,结果前端缓存同一请求在不同时段命中了不同路由,引发了很多诡异bug。

3.4 拦截器:更底层的“钩子”

拦截器一般比过滤器更细粒度。它是跑在请求进入业务逻辑之前或之后,可以访问到方法级别的上下文。在Spring MVC里是HandlerInterceptor,在Dubbo Filter里是InvokerInterceptor。它经常用来干这些事:

  • 透传用户身份到下游上下文
  • 度量(Metrics)采集,比如每个接口的耗时
  • 重试逻辑(配合RetryTemplate)
  • 动态路由覆写

我个人习惯把拦截器用在需要“跨越多个插件或过滤器”的场景。举个例子:用户登录后,拦截器把userInfo塞进ThreadLocal,后续的限流插件、日志插件都能直接从上下文拿,而不用重复解析。

3.5 四种机制怎么选?一张表说清楚

特性 插件 过滤器 断言 拦截器
执行位置 全局/自定义 链式,前后置 路由前 方法前后
典型用途 认证、限流、日志 内容修改、校验 路由、灰度 上下文传递、度量
是否修改载荷 可以 可以 不可以 可以
执行顺序 插件内无序 链式有序 与,或组合 线性有序
性能影响 中(热加载开销) 低 极低(纯逻辑) 低
我的建议:对于内部开发者平台,你优先用断言做路由分流,插件做通用能力,过滤器做请求/响应定制,拦截器用来兜底那些跨模块的上下文需求。别混用,不然排查问题时脑子会炸。

嗯,这就是网关扩展点的大致地图。下一回碰到具体场景,你就能对着这张表快速选型了。别忘了,扩展点只是工具,清楚业务逻辑才是核心。