尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Java 程序员第 45 阶段18:网关统一路由大模型接口,配合 Nacos 配置治理,网关高可用:集群部署、负载均衡与容灾方案
1. 为什么大模型网关必须做高可用当公司里所有大模型调用都收敛到一个网关入口后这个网关就从「一个转发组件」变成了全局单点。它挂掉对话、Embedding、生成能力全部不可用影响面比某个业务系统宕机大得多。所以高可用是网关落地的及格线不是加分项。我先把目标量化成三个指标后面所有配置都围绕它们展开。可用性全年不可用时间控制在 SLO 内比如 99.95% 对应全年约 4.4 小时。可扩展性流量翻倍时能水平扩容网关实例扛住。容错性后端大模型 Provider 抖动、超时、限流时网关能降级兜底不雪崩。整体架构是三层高可用。接入层用 SLB 或 Nginx 对多个网关实例做负载均衡消除网关单点。网关层是 N 个 Spring Cloud Gateway 无状态实例全部从 Nacos 拉取路由与配置彼此对等。Provider 层是大模型服务多实例注册到同一个注册中心网关通过lb://做客户端负载均衡。这套架构里 Nacos 既是配置中心下发路由、缓存开关、限流规则也是注册中心做服务发现。所有高可用策略都通过 Nacos 集中管理、动态生效和配置治理主线一脉相承。下面从 TaoToken 的接入准备开始一步步把可复制的配置搭起来。2. TaoToken 前置准备统一 Key 与 API 通道网关要统一路由大模型接口前提是有一个稳定的上游通道。TaoToken 在这里承担的角色是统一 Key 管理和 API 通道网关只需要面向一个兼容 OpenAI 的接口规范不用为每个厂商单独写适配。你可以先到官网了解整体能力再进控制台创建 Key。具体动作是这样打开 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 了解接入方式然后进入控制台 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 创建 API Key。Key 创建后只显示一次建议直接写进 Nacos 配置不要硬编码在代码里。API 基地址用 https://taotoken.net/api注意这个地址不加 UTM 参数保持干净。这里有个容易踩的坑很多人把 Key 直接写在application.yml里提交到 Git后面轮换 Key 时要改代码重新发版。正确做法是把 Key 作为 Nacos 配置项网关启动时拉取轮换时只改 Nacos 不动代码。配置骨架大概长这样api-key和base-url都从 Nacos 注入llm: gateway: base-url: https://taotoken.net/api api-key: ${LLM_API_KEY:sk-xxxx} connect-timeout: 3000 read-timeout: 60000如果你还在选模型阶段可以先用模型对话页面验证 Key 是否可用确认通道通了再往网关里接。地址是 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。长期做编码和 Agent 场景的话Coding Plan 会更省心入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。Key 和接入文档在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 与 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。3. 可复制配置网关集群 Nacos 治理3.1 无状态是横向扩容的前提网关本身不保存会话状态缓存是本地的、可丢失连接是短连接或中连接所以横向扩容毫无障碍。部署时每个网关实例配置相同的 Nacos 地址、相同的路由 DATA_ID启动后从 Nacos 拉取全量路由即可对外服务。下面这份配置可以直接复制把NACOS_ADDR换成你的实际地址spring: application: name: llm-gateway cloud: nacos: discovery: server-addr: ${NACOS_ADDR:127.0.0.1:8848} namespace: llm-prod group: LLM_GATEWAY config: server-addr: ${NACOS_ADDR:127.0.0.1:8848} namespace: llm-prod group: LLM_GATEWAY file-extension: yaml gateway: discovery: locator: enabled: truediscovery.locator.enabled开启基于服务发现的路由这样 Provider 实例上下线时网关能自动感知。路由规则本身也放 NacosDATA_ID 用llm-gateway-routes.yaml内容示例spring: cloud: gateway: routes: - id: llm-chat uri: lb://llm-provider predicates: - Path/api/llm/chat/** filters: - StripPrefix2 - id: llm-embed uri: lb://llm-provider predicates: - Path/api/llm/embed/** filters: - StripPrefix23.2 接入层负载均衡与优雅上下线多个网关实例前面挂一个 SLB 或 Nginx用轮询或最小连接把外部流量分摊到各网关。注意网关前面的反代要开启健康探测自动摘除不健康实例。对 SSE 流式路径Nginx 务必proxy_buffering off否则流式响应会被缓冲住前端迟迟收不到内容。upstream llm_gateway { least_conn; server 10.0.1.11:8080 max_fails3 fail_timeout15s; server 10.0.1.12:8080 max_fails3 fail_timeout15s; server 10.0.1.13:8080 max_fails3 fail_timeout15s; keepalive 64; } server { location /api/llm/ { proxy_pass http://llm_gateway; proxy_buffering off; proxy_read_timeout 120s; health_check uri/actuator/health interval5s; } }扩缩容时务必优雅。实例收到SIGTERM后先从 Nacos 和 SLB 摘流量等待在途请求处理完再退出。Spring Boot 的server.shutdown: graceful配合spring.lifecycle.timeout-per-shutdown-phase就能实现server: shutdown: graceful spring: lifecycle: timeout-per-shutdown-phase: 30s3.3 双层负载均衡策略高可用里有两层负载均衡含义不同容易混淆。外层 LB 是 SLB 或 Nginx 把流量分到多个网关实例。内层 LB 是网关把请求分到多个大模型 Provider 实例由 Gateway 的ReactiveLoadBalancerClientFilter基于服务发现完成也就是lb://service-name。内层策略默认是轮询。但大模型场景下不同 Provider 实例算力可能不均有的卡多有的卡少轮询会造成快的被拖慢、慢的被压垮。更优的是加权响应时间或一致性哈希。下面这张表帮你按场景选策略优点缺点大模型场景适配RoundRobin 轮询简单、均匀无视实例能力差异实例同构时可用Random 随机无状态波动大不推荐WeightedResponseTime慢实例少分流量需统计响应时间异构 GPU 集群推荐一致性哈希同 key 落同实例利于本地缓存实例变动时重分布带本地缓存时推荐最少连接偏好空闲实例需维护连接数流式长连接推荐Nacos 注册中心支持给每个实例设置weightGateway 的负载均衡会按权重分配。你可以在 Nacos 控制台把新版本 Provider 实例权重调小做灰度调大做放量流量配比由 Nacos 集中掌控。自定义选择器的骨架如下核心是取请求里的 tenant 或 model 作为哈希键再按权重选择public class LlmLoadBalancer implements ReactorServiceInstanceLoadBalancer { Override public MonoResponseServiceInstance choose(Request request) { // 1. 取请求中的 tenant / model 作为哈希键 // 2. 按 Nacos 实例 weight 做加权随机选择 // 3. 返回选中的 ServiceInstance交给 Gateway 转发 } }4. 验证请求故障转移与配置热更新配置写完必须验证否则高可用只是纸面文章。我分两个动作来测故障转移和配置热更新。故障转移验证启动两个网关实例注册到同一个 Nacos。用curl连续打 20 次请求观察是否均匀落到两个实例。然后手动停掉其中一个实例再打 20 次确认请求全部落到存活实例且没有报错。命令如下for i in $(seq 1 20); do curl -s -o /dev/null -w %{http_code} \ -X POST http://10.0.1.11:8080/api/llm/chat \ -H Content-Type: application/json \ -d {model:gpt-4o-mini,messages:[{role:user,content:hi}]} done echo预期结果是 20 个 200停掉一个实例后仍然全是 200说明接入层健康探测和网关无状态生效了。如果出现 502 或 503检查 Nginx 的max_fails和fail_timeout是否配置以及/actuator/health是否可访问。配置热更新验证在 Nacos 控制台修改llm-gateway-routes.yaml比如给llm-chat路由加一个AddResponseHeader过滤器保存后不重启网关直接再打一次请求看响应头里是否出现新加的字段。如果出现了说明 Nacos 配置监听生效。这一步很关键它决定了你后面调限流阈值、切 Provider 权重时能不能不重启。curl -s -D - -o /dev/null \ -X POST http://10.0.1.11:8080/api/llm/chat \ -H Content-Type: application/json \ -d {model:gpt-4o-mini,messages:[{role:user,content:hi}]} \ | grep -i x-gateway5. 本篇常见错排查5.1 网关启动报 Nacos 连接失败最常见的是server-addr写错或 namespace 不匹配。Nacos 的 namespace 用的是命名空间 ID不是名称控制台里复制 ID 再填。另外 group 要一致配置和发现用同一个 group否则拉不到配置。如果本地开发连远程 Nacos确认网络可达别用127.0.0.1却期望连到服务器。5.2 路由不生效请求 404先看spring.cloud.gateway.discovery.locator.enabled是否为 true再看 Nacos 里的路由 DATA_ID 是否和file-extension对应。比如file-extension: yamlDATA_ID 就得是xxx.yaml。还有StripPrefix的位数要对/api/llm/chat/**去掉两层前缀后才是 Provider 的真实路径位数错了就会 404。5.3 流式响应被缓冲前端收不到这是 Nginx 层的问题不是网关。确认proxy_buffering off加在了 SSE 路径的 location 里。另外proxy_read_timeout要够大大模型生成慢默认 60s 可能不够调到 120s 或更长。如果用了 SLB也要确认 SLB 侧没开响应缓冲。5.4 熔断降级不触发检查 Resilience4j 或 Sentinel 的规则是否真的下发到了网关。Sentinel 网关流控规则通过 Nacos 数据源下发时rule-type要写gw-flow写错成flow规则不会生效。另外降级过滤器的Order要足够小保证它在路由转发之前执行否则异常已经被下游处理掉了。5.5 优雅停机杀掉在途请求server.shutdown: graceful只对 Spring Boot 内嵌容器生效如果前面有 Nginx还要确保 Nginx 在实例摘流后不再转发新请求。顺序是先调 Nacos 注销接口摘流量等timeout-per-shutdown-phase时间再发SIGTERM。顺序反了在途请求会被直接切断。6. 限流保护与容灾兜底高可用不仅要防后端挂还要防自己被冲垮和把后端冲垮。网关是限流的最佳位置在流量入口统一做流控保护整条链路。Spring Cloud Gateway 集成 Sentinel 后可以基于路由 ID、API 分组、来源应用、参数做限流支持快速失败、排队等待、预热三种效果。spring: cloud: sentinel: transport: dashboard: ${SENTINEL_ADDR:127.0.0.1:8858} datasource: gw-flow: nacos: server-addr: ${NACOS_ADDR:127.0.0.1:8848} namespace: llm-prod groupId: LLM_GATEWAY dataId: sentinel-gateway-flow-rules rule-type: gw-flowNacos 里的规则示例按路由限流对话每秒 100 次快速失败Embedding 每秒 500 次排队等待[ { resource: llm-chat, count: 100, intervalSec: 1, controlBehavior: 0, burst: 20 }, { resource: llm-embed, count: 500, intervalSec: 1, controlBehavior: 2, maxQueueingTimeoutMs: 500 } ]controlBehavior里 0 是快速失败1 是预热2 是排队等待。对话用快速失败加友好报错Embedding 这种可短暂排队的用排队等待。更精细的还可以按model参数做热点限流某模型被刷爆时只拦该模型不影响其他模型。熔断降级方面用 Resilience4j 或 Sentinel 的熔断规则当对某个 Provider 的错误率或慢调用比例超过阈值自动跳闸后续请求在熔断窗口内直接走降级逻辑给 Provider 喘息时间。降级不是返回错误而是返回有业务意义的兜底比如返回缓存中的上一次结果或切换到备用 Provider或返回结构化的「模型繁忙」报文。Component Order(-3) public class LlmFallbackGlobalFilter implements GlobalFilter { private final CacheString, String fallbackCache; Override public MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) { return chain.filter(exchange) .onErrorResume(TimeoutException.class, e - fallback(exchange, 模型响应超时)) .onErrorResume(CallNotPermittedException.class, e - fallback(exchange, 熔断中已降级)) .onErrorResume(ResponseStatusException.class, e - fallback(exchange, 后端异常)); } private MonoVoid fallback(ServerWebExchange exchange, String reason) { String key exchange.getAttribute(cacheKey); String cached fallbackCache.getIfPresent(key); String body (cached ! null) ? cached : {\error\:\model_unavailable\,\reason\:\ reason \}; byte[] bytes body.getBytes(StandardCharsets.UTF_8); exchange.getResponse().getHeaders().add(X-Fallback, true); DataBuffer buf exchange.getResponse().bufferFactory().wrap(bytes); return exchange.getResponse().writeWith(Mono.just(buf)); } }多机房容灾的话网关集群与 Provider 集群在两个机房各部署一套Nacos 做跨机房同步接入层 SLB 配置主备机房健康探测主机房不可用时流量切到备机房。按业务重要性选容灾等级测试用单实例内部工具用双实例加 SLB生产默认多实例加熔断限流核心业务上多机房双活。落地清单我整理成几条网关无状态化所有策略走 Nacos随时扩缩容接入层健康探测探/actuator/health自动摘流优雅上下线用 graceful shutdown 加 Nacos 注销双层负载均衡外层 SLB 分到网关内层lb://加权或哈希分到 Provider熔断加降级兜底错误率超阈值跳闸降级返回缓存或友好报文入口限流用 Sentinel 网关流控经 Nacos 下发核心业务上多机房预案。到这里网关在统一路由加配置治理的基础上又补齐了高可用和容灾这层护甲。下一步可以把治理做得更严也就是谁能动配置、动了什么、能否审计。如果你还没把 Key 和通道准备好先去 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 创建接入细节看 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 长期编码场景直接上 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。
RELATED

相关推荐

多目标跟踪实战:给检测框一张稳定的“身份证”

多目标跟踪实战:给检测框一张稳定的“身份证”

做视觉的同学应该都有同感:单看一张图,检测模型能给出漂亮的框、准确的类别,但一旦切到视频,每一帧的框都是"陌生人"——没有ID、没有历史、没有前后联系。人眼能轻松追踪"左边那个人刚才走到了右边"&#xf…

📅 2026/9/26 18:18:44
大厂 MCP 面试实录:基于 OpenTelemetry 与 OAuth 2.1 的可重复集成测试方案设计(TaoToken 统一 Key 通道版)

大厂 MCP 面试实录:基于 OpenTelemetry 与 OAuth 2.1 的可重复集成测试方案设计(TaoToken 统一 Key 通道版)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/9/26 18:18:44
数字孪生落地实战:从数据链路到实时可视化与决策闭环

数字孪生落地实战:从数据链路到实时可视化与决策闭环

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/9/26 18:13:42
MORE NEWS

更多资讯

📰

Gitee不是Jira替代品,而是研发基础设施底座

1. 这不是一份“排行榜”,而是一份2026年研发团队真实选型决策手记你搜“2026 国产 Jira 替代方案排名”,大概率是刚被老板甩了一张PPT,上面写着“推进信创落地”“完成Jira国产化迁移”“Q3前完成工具链切换”。你点开各种公众号文章&#x…

📰

MarkText中文工作流重建手册:从安装到专业技术写作

1. MarkText不是Typora的平替,而是另一条技术路径的实践者MarkText中文版——这个在2024年GitHub趋势榜上反复出现的名字,常被新手误读为“Typora汉化版”或“免费替代品”。但实际接触过它的人都清楚:它根本不是Typora的影子,而是…

📰

Windows自动更新关闭全方案:从设置到防火墙的六层防御

1. 为什么“关闭自动更新”成了Win10/Win11用户最频繁的刚需操作?你有没有经历过这些瞬间:正赶着提交一份重要方案,屏幕右下角突然弹出“正在下载更新,预计剩余23分钟”;深夜调试一个关键脚本,系统毫无征兆…

📰

V100跑Qwen 27B从4到64 tok/s:显存、量化与推理引擎调优实战

拿到一台 V100 的时候,我当时心里很清楚:Qwen 27B 这模型肯定能跑,但跑得快不快,完全看你怎么伺候这块 2017 年的老卡。第一次部署完,实测只有 4 tok/s,输出速度慢到像在“蹦字”。后来花了两周时间做量化选…

📰

开源文档解析工具docling:从PDF到结构化数据,助力RAG知识库

1. docling是什么:它解决的正是知识库落地最头疼的环节做知识库、RAG(检索增强生成)或者文档问答相关项目的朋友,大概率都经历过这么一个让人抓狂的阶段:好不容易把PDF、Word、PPT、扫描件凑齐了,结果扔给模…

📰

剪映Hub深度拆解:AI生视频到剪辑的全链路整合实践

剪映这次把“Hub”这个概念抛出来的时候,我第一反应是:终于有人把AI生视频和剪辑之间那道墙正面推平了。过去大半年,我身边做短视频的朋友,包括我自己,都在一种极其拧巴的工作流里挣扎——在AI生成工具里跑来跑去跑提示…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬