Spring Boot Alibaba(三)----Sentinel

服务容错保护-Sentinel

一、 Sentinel 是个啥?为什么要用它?

1. 灵魂拷问:为什么要用?

想象一下这个场景:

上游服务(大哥)疯狂调用你的服务(小弟),你的服务又疯狂调用下游服务(小弟的跟班)。

突然,跟班(下游)挂了,或者大哥(上游)流量洪峰来了。

  • 后果 :你的服务(小弟)直接被夹在中间,要么被上游累死(资源耗尽),要么被下游拖死(线程阻塞)。最后,整个系统像多米诺骨牌一样,啪!全挂了! 这就是传说中的服务雪崩
2. Sentinel 登场

Sentinel(哨兵),阿里出品,必属精品。它是以流量为切入点的服务保护框架。

  • 流量控制(防上游)
    • 就像水闸,控制每秒通过的请求数(QPS)或者同时干活的线程数(Thread)。
    • 口号:上游大哥,慢点来,我顶不住啊!
  • 熔断降级(防下游)
    • 熔断:发现下游不对劲(响应慢、报错多),直接切断连接,眼不见心不烦。
    • 降级:熔断后不能干瞪眼啊,得返回个默认值(比如"系统繁忙"或空数据),给用户体验留条底裤。
    • 口号:下游不行我就撤,绝不恋战!

二、 Sentinel 的四大规则(武功秘籍)

Sentinel 怎么保护你?靠的就是规则!

1. 流控规则(最常用)
  • 流控 :直接对 URL 下手。比如 /hello 接口,限制 QPS=2。超过?直接拒绝,没商量。
  • 热点参数 :比如你有个接口查商品详情,参数是 id。如果 id=1001 的商品突然爆了,你可以单独限制这个参数,别让它把数据库打挂。
  • 授权 :黑白名单机制。比如只允许 origin=app 的请求访问,其他的(比如爬虫)统统踢走。
  • 系统:这是"上帝视角"。如果整个服务的负载(Load)或 CPU 飙高了,Sentinel 会自动开启限流,保住小命要紧。
2. 降级规则(保命符)

这里有三个维度,满足一个就触发熔断:

  • 异常比例 :5秒内,发了5次请求,如果有10%(0.1)都报错了 -> 熔断5秒
  • 异常数 :5秒内,发了5次请求,只要有1次报错 -> 熔断5秒
  • 慢调用比例 :5秒内,发了5次请求,如果有10%的请求超过1毫秒(RT)才返回 -> 熔断5秒
    • 注:这里的阈值根据业务实际情况调整,别设太死板哦。

️ 三、 从零开始:环境搭建与整合(保姆级教程)

光说不练假把式,咱们来点实操的!

1. 启动 Sentinel 控制台(Dashboard)

你得先有个地方看监控吧?

  • 下载 :去 GitHub 下载 sentinel-dashboard.jar
  • 启动 :命令行输入 java -jar sentinel-dashboard.jar
  • 访问 :浏览器打开 http://localhost:8080,账号密码默认都是 sentinel
  • 注意:这一步不做,后面规则都没地方配!
2. 引入依赖(Maven)

在你的 pom.xml 里加上这个"护身符":

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

如果是整合 Feign,记得还要有 Feign 的依赖哦。

3. 配置文件(application.yml)

告诉你的服务,Sentinel 控制台在哪里:

yaml 复制代码
spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080 # 控制台地址
        port: 8719 # 客户端端口,默认8719,被占用会自动+1

四、 Sentinel 整合 Feign(重中之重)

Consumer 调用 Provider 通常是用 Feign,所以熔断降级必须在 Feign 上做文章。

1. 开启 Feign 对 Sentinel 的支持

application.yml 中必须加这一句,否则 Feign 不会理你:

yaml 复制代码
feign:
  sentinel:
    enabled: true
2. 编写降级逻辑(Fallback)

当 Provider 挂了,Feign 得知道该怎么办。我们需要一个"备胎"工厂。

java 复制代码
@Component
public class UserFeignFallbackFactory implements FallbackFactory<UserFeign> {

    @Override
    public UserFeign create(Throwable t) {
        // t 就是报错的原因,可以打印日志
        return new UserFeign() {
            @Override
            public User getUserById(Integer id) {
                // 返回一个假数据,或者包含错误信息的对象
                return new User(id, "服务降级了:" + t.getMessage(), 0);
            }
        };
    }
}
3. 指定降级工厂

在你的 Feign 接口上贴上 fallbackFactory 标签:

java 复制代码
@FeignClient(value = "sentinel-provider", fallbackFactory = UserFeignFallbackFactory.class)
public interface UserFeign {
    @GetMapping("/user/{id}")
    User getUserById(@PathVariable("id") Integer id);
}

搞定!现在 Provider 挂了,Feign 会自动调用你的 Fallback 逻辑,用户看到的不再是 500 错误,而是友好的提示。


五、 全局异常处理(统一口径)

默认的 Sentinel 报错信息太丑了,而且格式不统一。我们要做一个"统一异常处理器"。

实现 BlockExceptionHandler 接口:

java 复制代码
@Component
public class GlobalBlockExceptionHandler implements BlockExceptionHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
        response.setContentType("application/json;charset=utf-8");
        Result result = null;
        
        // 判断是哪种异常
        if (e instanceof FlowException) {
            result = new Result(-1, "哎呀,被限流了,稍后再试...");
        } else if (e instanceof DegradeException) {
            result = new Result(-2, "服务降级了,功能暂时不可用...");
        } else if (e instanceof AuthorityException) {
            result = new Result(-4, "授权失败,你谁啊?");
        } else if (e instanceof SystemBlockException) {
            result = new Result(-5, "系统负载过高,正在自救...");
        }
        
        // 返回 JSON 给前端
        response.getWriter().write(new ObjectMapper().writeValueAsString(result));
    }
}

这样,不管触发什么规则,前端收到的都是统一的 JSON 格式,体验满分!


六、 规则持久化(告别"一重启就丢")

默认情况下,你在 Sentinel Dashboard 上配的规则都在内存里。服务一重启,或者控制台一关,规则全没了!这怎么行?我们需要把规则存到 Nacos 配置中心。

第一步:改造 Sentinel Dashboard

我们要让 Dashboard 能把规则推送到 Nacos。

  1. 下载 sentinel-dashboard-nacos-1.8.1.jar(这是阿里魔改过的版本,支持 Nacos)。

  2. 用压缩软件打开这个 jar 包(或者解压)。

  3. 找到 application.properties 文件,修改:

    properties 复制代码
    nacos.address=192.168.61.132:8848
  4. 重新打包(或者在解压目录下启动),启动这个新的 Dashboard。

第二步:微服务从 Nacos 拉取规则
  1. 引入依赖

    xml 复制代码
    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-datasource-nacos</artifactId>
    </dependency>
  2. 配置 application.yml

    yaml 复制代码
    spring:
      cloud:
        sentinel:
          datasource:
            ds1: # 数据源名称,随便起
              nacos:
                server-addr: ${spring.cloud.nacos.discovery.server-addr}
                namespace: sentinel # 建议单独搞个命名空间
                groupId: SENTINEL_GROUP
                dataId: ${spring.application.name}-flow-rules # 规则文件的ID
                rule-type: flow # 告诉 Sentinel 这个文件里存的是流控规则
                data-type: json # 数据格式
第三步:验证
  1. 在 Nacos 配置中心新建配置,Data ID 必须和上面配置的 dataId 一致。
  2. 内容填 JSON 格式的规则(可以去 Dashboard 导出一个看看格式)。
  3. 启动微服务,你会发现规则自动生效了!
  4. 这时候,哪怕 Sentinel Dashboard 挂了,只要 Nacos 在,规则就在!

总结

Sentinel 就是微服务的保镖。

  • 限流:防上游搞事。
  • 熔断降级:防下游拖后腿。
  • 整合 Feign:让远程调用更健壮。
  • 持久化:让规则永久生效。
相关推荐
电魂泡哥2 小时前
Mysql索引下推、索引跳跃、索引覆盖
后端
渡边时雨2 小时前
大多数人搭 RAG,第一步就错了
后端·llm
2301_780789662 小时前
2025年ddos防护还能防护住越来越大的ddos攻击吗
网络·后端·tcp/ip·网络安全·架构·ddos
程序员柒叔2 小时前
Agent / Subagent / Swarm 解析:ClaudeCode源码深度解读
人工智能·后端
ERBU DISH2 小时前
如何使用Spring Boot框架整合Redis:超详细案例教程
spring boot·redis·后端
火莲华2 小时前
Go刨根问底系列 sync.Mutex part3
后端
倚栏听风雨2 小时前
Claude-Agent-SDK:Streaming Input 流式输入
后端
神奇小汤圆2 小时前
面试官灵魂拷问:为什么 SQL 语句不要过多的 join?
后端
notfound40432 小时前
解决SpringCloudGateway用户请求超时导致日志未记录情况
java·spring boot·spring·gateway·springcloud