第3篇:Sentinel熔断降级实战:大模型接口抖动时的服务兜底方案

开篇痛点段

在上一篇我们搭建了多厂商统一LLM调用客户端,做到了模型厂商无感切换。 但这里有一个极易被忽略的致命问题:大模型接口和普通HTTP接口完全不是一回事。 普通接口几十毫秒返回,LLM动辄1~5秒,遇到厂商侧抖动、服务故障,响应会更久。

很多同学只加了重试逻辑:接口超时就重试2次。 这个方案,只能解决瞬时抖动(比如一次网络闪断)。 但如果上游大模型服务挂了5分钟、大面积超时报错会发生什么? 用户请求源源不断进来 → 每一次都去调用LLM → 每一次都超时卡住线程 → 线程池快速打满 → 所有依赖这个线程池的接口(查询、提交、其他业务)全部阻塞,直接雪崩。

我们需要一层"保险丝":当模型服务持续异常/持续慢,直接切断流量,不再放行新请求去打LLM,也就是熔断降级。 这就是Sentinel在LLM场景里的核心价值:慢调用熔断 + 异常统计 + 快速失败,故障的时候保护我们自己的业务,而不是被动被上游拖死。

前置回顾:本篇依赖第2篇的ILlmService、LlmServiceFactory统一底座。 核心认知先行:熔断 ≠ 重试,二者是搭档,顺序绝对不能颠倒。 正确顺序:单次请求内部先做有限重试(应对瞬时抖动)→ 重试依然失败 → 本次结果计入Sentinel的统计窗口 → 达到阈值触发熔断,一段时间内直接快速降级,不再访问LLM。

一、引入依赖

使用Spring Cloud Alibaba Sentinel,适配SpringBoot3环境:

复制代码
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    <version>2023.0.1.0</version>
</dependency>

补充说明:SpringBoot3请选用2023.0.x版本,不要用老的2022版本,会存在注解、自动装配兼容问题。

二、封装业务调用层,增加Sentinel资源注解

我们单独抽出LlmBizService作为AI业务门面,把LLM调用标记为Sentinel资源,分开两个处理器:

  • blockHandler:Sentinel限流、熔断、排队规则触发时执行(平台流量管控类拦截)

  • fallback:业务本身抛出异常(调用LLM报错、返回异常)的兜底降级 很多新手踩坑:分不清block和fallback,全部写在一个方法里,故障排查根本分不清是被熔断了,还是LLM本身报错。

    import com.alibaba.csp.sentinel.annotation.SentinelResource;
    import com.alibaba.csp.sentinel.slots.block.BlockException;
    import org.springframework.ai.chat.model.ChatResponse;
    import org.springframework.stereotype.Service;

    @Service
    public class LlmBizService {

    复制代码
      private final LlmServiceFactory factory;
    
      public LlmBizService(LlmServiceFactory factory) {
          this.factory = factory;
      }
    
      /**
       * Sentinel资源:llm_chat_api
       * blockHandler:熔断/限流触发的拦截逻辑
       * fallback:业务调用异常兜底
       */
      @SentinelResource(value = "llm_chat_api",
              blockHandler = "blockHandler",
              fallback = "fallbackHandler")
      public ChatResponse chat(String modelKey, String prompt, LlmRequestParam param) {
          ILlmService llm = factory.getService(modelKey);
          return llm.chat(prompt, param);
      }
    
      /**
       * 熔断、限流触发:属于流量管控,短时间不允许放行请求
       */
      public ChatResponse blockHandler(String modelKey, String prompt, LlmRequestParam param, BlockException e) {
          // 生产建议:返回标准化VO,给前端友好提示,而不是直接抛原生异常
          throw new RuntimeException("当前AI服务压力过高,已开启熔断保护,请稍后再尝试提问");
      }
    
      /**
       * LLM调用业务异常兜底:超时、厂商返回报错、鉴权失败等
       */
      public ChatResponse fallbackHandler(String modelKey, String prompt, LlmRequestParam param, Exception e) {
          // 可以在这里扩展:自动切换备用模型,而不是直接报错!
          throw new RuntimeException("AI模型调用暂时异常,请稍后重试");
      }

    }

👉 扩展点 : fallback里面不要只抛异常!你可以在这里复用之前的工厂,实现主模型熔断自动切备用模型: 主模型触发异常进入fallback → 自动传入backup的modelKey,调用备用服务商,给用户无感容灾。 示例思路(伪代码,方便你后续拓展):

复制代码
// fallback内容灾逻辑
if("tongyi".equals(modelKey)){
    return factory.getService("deepseek").chat(prompt,param);
}

三、代码方式配置熔断规则(慢调用比例熔断)

Sentinel有两种配置模式:代码硬编码、控制台动态推送。 代码方式适合本地调试、小体量项目;线上正式环境优先控制台。 这里我们配置LLM场景最适合的:慢请求比例熔断,而不是异常比例熔断。

为什么LLM优先慢调用熔断? 很多时候模型没有抛报错,只是响应极慢,线程卡死,这种场景异常数是0,异常熔断完全感知不到,慢调用熔断刚好捕获这类隐形风险。

复制代码
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleType;
import jakarta.annotation.PostConstruct;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;

@Component
public class SentinelRuleConfig {

    @PostConstruct
    public void initDegradeRule() {
        List<DegradeRule> rules = new ArrayList<>();
        DegradeRule rule = new DegradeRule();
        // 和@SentinelResource的value保持一致,资源名必须匹配
        rule.setResource("llm_chat_api");
        // LLM场景:超过2000ms判定为慢调用,普通接口一般是几百ms,这里要单独放大阈值
        rule.setSlowRtThreshold(2000);
        // 统计窗口:10s内的数据用来统计
        rule.setStatIntervalMs(10000);
        // 慢调用占比超过50%,触发熔断
        rule.setSlowRatioThreshold(0.5);
        // 最小请求数:10s内至少有5个请求才做统计,避免少量请求误熔断
        rule.setMinRequestAmount(5);
        // 熔断时长:10秒。熔断开启后,10s内所有新请求直接走blockHandler快速失败,不调用LLM
        rule.setTimeWindow(10);
        // 规则类型:慢调用比例熔断
        rule.setDegradeRuleType(DegradeRuleType.SLOW_REQUEST_RATIO);
        rules.add(rule);
        DegradeRuleManager.loadRules(rules);
    }
}

四、核心时序图

复制代码
flowchart LR
    A[用户请求进入] --> B[本地重试逻辑(最多N次,解决瞬时抖动)]
    B --> C{重试成功?}
    C --成功--> Z[返回结果]
    C --全部重试失败--> D[请求进入Sentinel资源统计]
    D --> E{是否已经熔断打开?}
    E --已熔断--> F[执行blockHandler,快速降级返回]
    E --未熔断--> G[发起真实LLM远程调用]
    G --> H{调用正常返回?}
    H --正常--> I[统计正常,返回结果]
    H --超时/报错/慢--> J[计入慢调用/异常统计]
    J --> K{达到熔断阈值?}
    K --达到--> L[开启熔断窗口,timeWindow时间内拦截新流量]
    K --未达到--> M[继续放行下一次请求]

五、LLM专属踩坑清单

  1. 阈值不能照搬普通接口 LLM接口RT天生高,普通后端接口500ms算慢,LLM起步建议2~3s作为慢调用阈值。业务是长文本生成、Agent多轮调用的场景,甚至要放到4s,阈值太小会频繁误熔断。
  2. 熔断降级返回要标准化,面向前端友好 不要直接抛出框架原生英文异常、堆栈信息暴露给前端。统一封装返回体,区分两类提示:
  • block(熔断限流):服务繁忙保护提示
  • fallback(模型报错):模型调用异常提示 前端可以根据错误码展示不同UI,甚至展示排队弹窗。
  1. 顺序红线:重试在内,熔断在外,绝对不能反过来 如果先熔断再重试:熔断打开的时候,重试还不断发起调用,熔断完全失效,雪崩依旧发生。 正确设计:重试是单次请求内部的自救;熔断是宏观窗口级别的流量保护。
  2. 线上强烈推荐接入Sentinel控制台 代码写死规则只适合测试环境。接入控制台后,可以在线实时看QPS、慢调用占比、熔断状态;动态修改RT阈值、熔断时长,不用重启服务。 生产LLM业务波动大,大促、营销活动的时候,随时调参非常关键。
  3. 熔断窗口内不是永久拒绝 timeWindow是熔断持续时间,时间到之后,Sentinel会进入半开状态:放行少量探测请求。探测请求成功,自动关闭熔断;探测继续失败,重新打开熔断,自动恢复逻辑不用自己写。
  4. 多模型资源隔离 如果同时有通义、DeepSeek多个模型,不要共用同一个Sentinel资源名。 一个厂商挂了,不要把另外一个正常的模型一起熔断,分开资源、分开规则,做到厂商之间故障隔离。

六、小结

到这里,我们通过Sentinel慢调用熔断,给LLM调用链路装上了保险丝。当上游模型持续变慢、故障时,自动挡住源源不断的用户请求,避免线程池耗尽、服务雪崩。 熔断解决了"故障的时候保护服务",但是还有另外一类场景:营销活动、推广引流,瞬间涌入大量用户提问。哪怕模型本身是健康的,并发量直接打满厂商Token额度、接口QPS上限,瞬间被厂商限流封禁。 下一章,限流 & 排队策略:控制LLM的并发请求数量,平滑流量尖峰,守住厂商额度上限。

本专栏持续更新Java+SpringAI生产落地实战,全部代码可直接改造上线,收藏不迷路。如果你正在搭建内部知识库、智能客服AI能力,欢迎持续跟进。

相关推荐
lisw0511 分钟前
理解推理大语言模型的可监控性!
人工智能·语言模型·自然语言处理
天天被压力18 分钟前
【A股分钟级高频数据完全手册 #06】北交所分钟级数据接口:京市股票Pro版最新分时
java·人工智能·python
在所不辞兄20 分钟前
为什么学习率预热(warmup)能显著改善Transformer等大模型的训练稳定性?
人工智能·深度学习·神经网络·机器学习·智能仿真
天天被压力24 分钟前
【A股分钟级高频数据完全手册 #05】指数历史分钟数据接口:Pro版沪深指数分时回放
java·人工智能·python
captain37640 分钟前
▲统一功能——DispatcherServlet源码分析
java·spring·java-ee·log4j·maven
金銀銅鐵1 小时前
JDK 21 中 List.of 的实现细节:从 List12 到 ListN
java·后端·ai编程
ndz1 小时前
在 ModelFold 使用 Claude:无需代理,稳定可靠的日常开发体验
人工智能·api
adinnet20261 小时前
研发提效实战:AI智能体接手代码审查、 文档生成和技术沉淀
人工智能·小艾智能体·ai研发助手·代码审查自动化
寂寞的船1 小时前
【Unity知识速递】第5期 Unity 6.2 深度解析:AI Assistant 登场,World Space UI 与 Sentis 全面升级
人工智能·ui·unity