新闻详情

新闻详情

首页 / 资讯中心 / 详情

Java 程序员第 45 阶段18:网关统一路由大模型接口,配合 Nacos 配置治理,网关高可用:集群部署、负载均衡与容灾方案

发布时间:2026/9/26 18:18:39来源:尧图网络
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

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

罗技GHUB离线安装包部署指南:21.03.24稳定版安装与避坑 2026/9/26 20:05:43

罗技GHUB离线安装包部署指南:21.03.24稳定版安装与避坑

1. 为什么罗技GHUB的离线部署值得单独写一篇罗技GHUB这个驱动软件,用过罗技外设的人基本都绕不开它。G系列鼠标、键盘、耳机、方向盘,想要改键、调DPI、设宏、同步灯光,都得靠它。但问题在于,GHUB的在线安装体验一直不算稳定——下…

阅读更多 →
Ghidra逆向工程实战:从安装配置到脚本化自动化分析 2026/9/26 20:05:43

Ghidra逆向工程实战:从安装配置到脚本化自动化分析

1. 为什么我最终把主力逆向工具换成了Ghidra第一次接触Ghidra是几年前的一个固件分析项目。当时手里有一套设备固件需要做漏洞挖掘,IDA Pro的授权费用让团队犹豫了很久,而免费方案里能打的实在不多。抱着试试看的心态装了Ghidra,结果一个下午…

阅读更多 →
AI安全测试沙箱实战:容器化隔离与渗透测试指南 2026/9/26 20:05:37

AI安全测试沙箱实战:容器化隔离与渗透测试指南

1. 为什么AI安全测试不能直接上生产环境 1.1 一个真实的教训:删库只需要一条指令 去年帮一个朋友的公司做应急响应,事情的起因特别简单:他们内部搞了个AI智能体,想测试一下自动化工单处理能力,结果开发同学图省事&…

阅读更多 →
告别补丁式防护:从零构建数据安全架构与治理体系(含实战代码) 2026/9/26 20:05:11

告别补丁式防护:从零构建数据安全架构与治理体系(含实战代码)

告别补丁式防护:从零构建数据安全架构与治理体系(含实战代码) 很多团队做数据安全,是这么干的:出了一次数据泄露,赶紧买个 DLP;被监管点名了,临时补个加密;业务方喊数据…

阅读更多 →
AI操作硬件的门槛有多高?我花一个晚上、两百多块钱,亲手试出了答案 2026/9/26 20:05:11

AI操作硬件的门槛有多高?我花一个晚上、两百多块钱,亲手试出了答案

20:51,书房。 桌上摊着一块刚拆封的开发板、一袋传感器模块、一把杜邦线。板子插上USB,我盯着它看了半天,问出今晚的第一个问题:“这东西要不要按电源键?”——答案是,这块板没有电源键,USB一插…

阅读更多 →
OpenCode终端AI编程助手安装配置与模型接入全指南 2026/9/26 20:05:11

OpenCode终端AI编程助手安装配置与模型接入全指南

1. 为什么我要在终端里折腾 OpenCode 第一次听说 OpenCode 是在一个开发群里,有人甩了张截图,终端里直接跟 AI 对话改代码,不用切浏览器、不用开 IDE 插件,敲个命令就能让模型读文件、改函数、跑测试。当时我的第一反应是&#xf…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉