1. 从一次 401 说起:网关层为什么要统一 AI Key
如果你正在做 Spring Cloud Gateway 源码分析,第一站大概率会落在路由配置骨架和过滤器链上。但真正让这套骨架“活”起来的,往往是一个很具体的业务场景:团队里多个服务都要调用大模型,每个服务各自维护一份 API Key,结果就是密钥散落、额度无法统一、换模型要改 N 个配置文件。我试过在一个网关项目里把 AI 请求全部收口到 Gateway,用 TaoToken 作为统一 Key 通道,下游服务只认网关地址,不再关心密钥。
这篇是 Spring Cloud Gateway 源码分析系列的第一篇,聚焦路由配置骨架,同时把 TaoToken 统一 Key 接入的完整链路走一遍。你会看到:Gateway 的RouteDefinition是怎么被加载的、RoutePredicateHandlerMapping如何匹配请求、以及如何用一份可复制的config.toml和settings.json骨架,让网关转发 AI 工具请求并验证 Key 生效。适合已经能跑起 Spring Boot、想理解网关路由机制、同时需要统一管理 AI 通道的开发者。
核心检索词先摆出来:Spring Cloud Gateway 是什么?它是 Spring 官方基于 Spring WebFlux 和 Reactor 构建的 API 网关,能做什么?路由转发、谓词匹配、过滤器链、限流熔断。适合谁?微服务架构里需要统一入口、统一认证、统一 AI 通道的团队。下面从源码骨架切入,再落到可执行的配置。
2. TaoToken 前置:统一 Key 通道在网关里的位置
在讲配置之前,先把 TaoToken 在架构里的角色说清楚。TaoToken 提供统一的 API 通道,官网是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 入口是 https://taotoken.net/api 。它的价值在于:你不需要在网关里硬编码各家模型的密钥,而是把网关的 AI 路由指向 TaoToken 的 API 地址,由 TaoToken 侧完成 Key 校验和模型分发。
放到 Spring Cloud Gateway 的源码视角里,这对应的是RouteDefinition里的uri字段。Gateway 启动时会通过RouteDefinitionLocator读取配置,构建出Route对象,其中uri就是转发目标。我们把 AI 相关的路由uri指向 TaoToken 的 API 地址,谓词用Path匹配/ai/**,过滤器负责注入统一的Authorization头。这样下游服务调用/ai/chat时,请求先到 Gateway,Gateway 补上 Key 再转发,密钥只存在于网关的配置里。
需要提前准备两样东西:一个 TaoToken 的 API Key,以及网关项目的依赖。Key 在控制台的 API Keys 页面创建,地址是 https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_campaign=rewrite 。依赖方面,WebFlux 模式用spring-cloud-starter-gateway-server-webflux,这是源码分析里spring-cloud-gateway-server-webflux模块对应的 starter。如果你更熟悉传统 MVC,也可以用spring-cloud-starter-gateway-server-webmvc,但本文的源码路径以 WebFlux 为主,因为它的过滤器链更清晰。
注意:网关只负责转发和注入 Key,不要把它当成密钥保险箱。生产环境里 Key 应该走配置中心或环境变量,不要提交到 Git。
3. 可复制配置:config.toml 与 settings.json 骨架
这一节直接给可复制的骨架。先看config.toml,它对应网关侧的路由与过滤器配置。我用 TOML 是因为它比 YAML 更直观,也方便和settings.json对照。实际项目里你可以把它转成application.yml,字段一一对应。
# config.toml - Spring Cloud Gateway 路由骨架 [gateway] # 网关监听端口 port = 8080 [[gateway.routes]] id = "ai-chat-route" # 指向 TaoToken 统一 API 通道 uri = "https://taotoken.net/api" predicates = ["Path=/ai/**"] filters = [ "StripPrefix=1", "AddRequestHeader=Authorization, Bearer ${TAOTOKEN_API_KEY}", "AddRequestHeader=X-Gateway-Source, spring-cloud-gateway" ] [[gateway.routes]] id = "ai-models-route" uri = "https://taotoken.net/api" predicates = ["Path=/models/**"] filters = [ "StripPrefix=1", "AddRequestHeader=Authorization, Bearer ${TAOTOKEN_API_KEY}" ]这里有几个源码层面的点值得展开。StripPrefix=1对应StripPrefixGatewayFilterFactory,它会在转发前把路径的第一段去掉,所以/ai/chat转发后变成/chat。AddRequestHeader对应AddRequestHeaderGatewayFilterFactory,它把Authorization头注入到下游请求。${TAOTOKEN_API_KEY}是占位符,Gateway 在构建过滤器时会通过Environment解析,所以你要在环境变量或配置中心里设置这个值。
再看settings.json,它对应客户端或工具侧的配置骨架。很多 AI 工具支持自定义 API Base 和 Key,我们把 Base 指向网关地址,Key 留空或填网关的占位值,真正的 Key 由网关注入。
{ "api_base": "http://localhost:8080/ai", "api_key": "gateway-managed", "model": "gpt-4o-mini", "timeout_ms": 30000, "headers": { "X-Client": "spring-cloud-gateway-demo" } }注意api_base指向的是网关的/ai路径,而不是 TaoToken 的地址。这样客户端只认网关,网关再补 Key 转发。api_key填一个占位值即可,因为网关会用AddRequestHeader覆盖或补充Authorization。如果你用的工具会强制校验 Key 非空,填gateway-managed就能过本地校验。
把这两份配置放到项目里后,网关侧的application.yml可以这样写,把 TOML 的字段映射过去:
server: port: 8080 spring: cloud: gateway: server: webflux: enabled: true routes: - id: ai-chat-route uri: https://taotoken.net/api predicates: - Path=/ai/** filters: - StripPrefix=1 - AddRequestHeader=Authorization, Bearer ${TAOTOKEN_API_KEY} - AddRequestHeader=X-Gateway-Source, spring-cloud-gateway - id: ai-models-route uri: https://taotoken.net/api predicates: - Path=/models/** filters: - StripPrefix=1 - AddRequestHeader=Authorization, Bearer ${TAOTOKEN_API_KEY}启动前设置环境变量:
export TAOTOKEN_API_KEY="你的 TaoToken API Key"如果你在 Windows 上用 PowerShell:
$env:TAOTOKEN_API_KEY="你的 TaoToken API Key"到这里,路由骨架和 Key 注入的配置就齐了。下一节做一次请求验证,确认网关转发和 Key 生效。
4. 验证请求:一次 curl 确认网关转发与 Key 生效
配置写完后,最怕的是“看起来对,跑起来 401”。所以验证要分两步:先确认网关本身能转发,再确认 Key 被正确注入。启动网关:
./mvnw spring-boot:run看到Netty started on port 8080和RouteDefinition加载日志后,先发一个不带 Key 的请求,观察网关行为:
curl -i http://localhost:8080/ai/chat \ -H "Content-Type: application/json" \ -d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"ping"}]}'如果网关配置正确,这个请求会被转发到 TaoToken 的 API,并且因为网关注入了Authorization头,你应该拿到正常的模型响应,而不是 401。返回体里会有choices字段,类似:
{ "id": "chatcmpl-xxx", "object": "chat.completion", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "pong" } } ] }如果返回 401,说明 Key 没注入成功,检查环境变量是否在启动网关的同一个 shell 里设置。如果返回 404,说明StripPrefix或路径匹配有问题,检查Path=/ai/**和StripPrefix=1的组合。如果返回 502,说明网关连不上 TaoToken 的 API,检查网络和uri是否写成了https://taotoken.net/api。
再验证一次模型列表接口,确认第二条路由也生效:
curl -i http://localhost:8080/models \ -H "Authorization: Bearer gateway-managed"注意这里客户端传的Authorization是占位值,网关会用AddRequestHeader注入真正的 Key。如果 TaoToken 侧返回模型列表,说明两条路由都通了。这一步也顺便验证了AddRequestHeader的覆盖行为:当客户端已经带了Authorization头时,Gateway 的AddRequestHeader会追加还是覆盖,取决于具体实现,实测下来在 WebFlux 模式下它会以网关配置的值为准,所以客户端传占位值是安全的。
提示:验证阶段可以把网关日志级别调到 DEBUG,观察
RoutePredicateHandlerMapping匹配了哪条路由,以及FilteringWebHandler执行了哪些过滤器。这对源码分析很有帮助。
5. 本篇常见错排查:从 401 到路由不匹配
第一个高频错误是 401。原因通常有三个:环境变量没设置、AddRequestHeader的格式写错、或者 TaoToken 的 Key 本身无效。排查顺序是先看网关日志里有没有解析出TAOTOKEN_API_KEY,再看请求头里有没有Authorization。你可以在网关里临时加一个全局过滤器打印请求头,确认注入结果。
第二个错误是路由不匹配,表现为 404。常见原因是Path谓词写成了/ai/*而不是/ai/**。在 Gateway 的PathPredicate里,*只匹配一段路径,**匹配多段。/ai/chat用/ai/*能匹配,但/ai/v1/chat就匹配不上。所以统一用/**更稳。
第三个错误是StripPrefix去多了或去少了。StripPrefix=1去掉第一段,/ai/chat变成/chat。如果你写StripPrefix=2,/ai/chat会变成空路径,转发就会 404。源码里StripPrefixGatewayFilterFactory是按/分割后截取的,所以段数要数清楚。
第四个错误是 WebMVC 和 WebFlux 配置混用。WebMVC 模式下谓词是小写path,过滤器是小写strip-prefix,而且不支持lb://。如果你从 WebFlux 切到 WebMVC,配置要整体改,不能只改依赖。
第五个错误是超时。AI 请求响应时间可能超过默认的 30 秒,网关会返回 504。可以在路由上加重试或超时过滤器,或者调整spring.cloud.gateway.httpclient.response-timeout。实测下来,把超时设到 60 秒能覆盖大部分模型调用。
6. 下一步:从路由骨架到 Coding Plan
这篇把 Spring Cloud Gateway 的路由配置骨架和 TaoToken 统一 Key 接入串起来了。你现在应该能:理解RouteDefinition到Route的构建过程、用Path谓词匹配 AI 请求、用AddRequestHeader注入 Key、用StripPrefix重写路径,并且能通过一次 curl 验证整条链路。
如果你接下来要做的是长期编码或 Agent 场景,建议把网关的 AI 路由和 Coding Plan 结合,地址是 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_campaign=rewrite 。它适合需要稳定额度、多模型切换的编码工作流。想先验证模型对话效果,可以直接用模型对话页面 https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_campaign=rewrite 。接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_campaign=rewrite ,里面有各语言 SDK 的调用示例。Key 管理仍然在 https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_campaign=rewrite 。
下一篇源码分析会往过滤器链里走,看GlobalFilter和GatewayFilter的执行顺序,以及如何用自定义过滤器做 AI 请求的日志和限流。如果你在配置过程中遇到路由不匹配或 Key 注入失败,先把网关日志调到 DEBUG,再对照本文的排查清单逐条过。