java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringCloud Alibaba Sentinel 使用

SpringCloud Alibaba Sentinel 从入门到精通

作者:tsyjjOvO

本文介绍了Sentinel的核心概念、使用方式及规则配置,Sentinel是阿里巴巴开源的流量控制框架,主要应用于流量控制、熔断降级等场景,文中有详细的规则配置示例,并介绍了如何与Feign整合,感兴趣的朋友一起看看吧

前言

在微服务架构中,服务间的依赖关系复杂,一个服务的故障可能引发连锁反应,导致整个系统雪崩。Sentinel 作为阿里巴巴开源的流量控制框架,能从流量控制、熔断降级等维度保护服务稳定性。本文将从实战角度,完整讲解 Sentinel 的核心概念、使用方式及各类规则配置。

一、Sentinel 核心概念

1.1 什么是 Sentinel

Sentinel(分布式系统的流量防卫兵)以流量为切入点,提供流量控制熔断降级系统负载保护等能力,保障微服务高可用。

1.2 核心概念

二、环境准备

2.1 搭建基础微服务

2.1.1 服务提供者(sentinel-provider)

application.yml

server:
  port: 9090
spring:
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.209.129:8848
  application:
    name: sentinel-provider

核心服务类

@Service
public class UserServiceImpl implements UserService {
    @Override
    public User getUserById(Integer id) {
        // 模拟网络延时
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return new User(id,"王粪堆-provider",18);
    }
}

2.1.2 Feign 接口(sentinel_feign)

@FeignClient("sentinel-provider")
public interface UserFeign {
    @RequestMapping(value = "/provider/getUserById/{id}")
    public User getUserById(@PathVariable Integer id);
}

2.1.3 服务消费者(sentinel_consumer)

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springcloud_parent</artifactId>
        <groupId>com.hg</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>sentinel_consumer</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.hg</groupId>
            <artifactId>springcloud_common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--feign接口-->
        <dependency>
            <groupId>com.hg</groupId>
            <artifactId>sentinel_feign</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--Sentinel核心依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
    </dependencies>
</project>

application.yml

server:
  port: 8080
  tomcat:
    max-threads: 10 # 降低tomcat并发,便于测试雪崩
spring:
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.209.129:8848
    sentinel:
      transport:
        dashboard: 127.0.0.1:8080 # Sentinel控制台地址
feign:
  client:
    config:
      default:
        connectionTimeout: 5000
        readTimeout: 5000
  sentinel:
    enabled: true # 开启Feign整合Sentinel

三、Sentinel 快速入门

3.1 方式 1:硬编码(抛异常方式)

@RestController
@RequestMapping("/consumer")
public class ConsumerController {
    @RequestMapping(value = "/hello")
    public String hello() {
        Entry entry = null;
        try {
            // 定义资源
            entry = SphU.entry("/consumer/hello");
            return "Hello Sentinel!!!";
        } catch (BlockException e) {
            // 限流兜底逻辑
            return "接口被限流了, exception: " + e;
        }finally {
            if (entry != null) {
                entry.exit();
            }
        }
    }
    // 初始化限流规则
    @PostConstruct
    public void initFlowQpsRule() {
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule1 = new FlowRule();
        rule1.setResource("/consumer/hello"); // 资源名
        rule1.setGrade(RuleConstant.FLOW_GRADE_QPS); // 按QPS限流
        rule1.setCount(2); // QPS阈值2
        rules.add(rule1);
        FlowRuleManager.loadRules(rules);
    }
}

3.2 方式 2:注解方式(推荐)

@RestController
@RequestMapping("/consumer")
public class ConsumerController {
    // 开启Sentinel注解支持
    @Bean
    public SentinelResourceAspect sentinelResourceAspect(){
        return new SentinelResourceAspect();
    }
    @RequestMapping(value = "/hello2")
    @SentinelResource(value="/consumer/hello2",blockHandler = "blockHandlerMethod")
    public String hello2() {
        return "Hello Sentinel2!!!";
    }
    // 限流兜底方法
    public String blockHandlerMethod(BlockException e){
        return "接口被限流了, exception: " + e;
    }
    @PostConstruct
    public void initFlowQpsRule() {
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule1 = new FlowRule();
        rule1.setResource("/consumer/hello2");
        rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule1.setCount(2);
        rules.add(rule1);
        FlowRuleManager.loadRules(rules);
    }
}

3.3 Sentinel 控制台使用

3.3.1 启动控制台

# 下载地址:https://github.com/alibaba/Sentinel/releases
java -jar sentinel-dashboard-1.8.1.jar

访问 http://localhost:8080,默认账号 / 密码:sentinel/sentinel。

3.3.2 接入控制台

消费者配置文件中添加:

spring:
  cloud:
    sentinel:
      transport:
        dashboard: 127.0.0.1:8080

访问任意接口(如 http://127.0.0.1:8080/consumer/hello3),控制台即可识别服务。

四、Sentinel 核心规则配置

4.1 流量控制规则

流量控制是 Sentinel 最核心的功能,通过限制 QPS / 线程数,防止服务被压垮。

4.1.1 核心配置项说明

配置项说明
资源名唯一标识,默认请求路径
针对来源限制调用方(默认 default,不区分来源)
阈值类型QPS(每秒请求数)/ 线程数
流控模式直接(限流当前接口)/ 关联(关联接口阈值触发限流)/ 链路(指定入口限流)
流控效果快速失败 / Warm Up(预热)/ 排队等待

4.1.2 典型场景配置

(1)QPS 限流

(2)Warm Up(预热限流)

(3)排队等待

4.2 热点参数限流

对接口参数做精细化限流,支持参数例外项(如特定 ID 放宽阈值)。

@RequestMapping(value = "/getUserById/{id}")
@SentinelResource(value = "getUserById", blockHandler = "blockHandlerMethod")
public User getUserById(@PathVariable Integer id) {
    return userFeign.getUserById(id);
}
// 热点参数限流兜底方法
public User blockHandlerMethod(Integer id, BlockException e) {
    return new User(id, "热点参数限流触发", 0);
}

4.3 熔断降级规则

当接口响应慢 / 异常比例高时,暂时切断调用,避免级联故障。

4.3.1 三种熔断策略

策略触发条件
慢调用比例慢调用(RT 超过阈值)占比超过设定值,且请求数≥最小请求数
异常比例异常请求占比超过设定值,且请求数≥最小请求数
异常数异常请求数超过设定值,且请求数≥最小请求数

4.3.2 配置示例(慢调用比例)

4.4 授权规则

基于请求来源做黑白名单控制,适合接口访问权限管控。

4.4.1 实现来源解析

@Component
public class RequestOriginParserDefinition implements RequestOriginParser {
    @Override
    public String parseOrigin(HttpServletRequest request) {
        // 从请求参数获取来源标识(可替换为请求头、Session等)
        return request.getParameter("origin");
    }
}

4.4.2 规则配置

4.5 系统规则

针对整个应用的全局规则(粒度粗,慎用),支持:

五、Sentinel 高级特性

5.1 自定义兜底逻辑(blockHandler)

5.1.1 同级别兜底(当前类)

@SentinelResource(value = "getUserById", blockHandler = "blockHandlerMethod")
public User getUserById(@PathVariable Integer id) {
    return userFeign.getUserById(id);
}
// 兜底方法(参数与原方法一致,最后加BlockException)
public User blockHandlerMethod(Integer id, BlockException e) {
    return new User(0, "接口被流控/熔断:"+e, 0);
}

5.1.2 外置兜底类(解耦)

// 外置兜底类(方法必须static)
public class BlockHandlerClass {
    public static User blockHandlerMethod(Integer id, BlockException e) {
        return new User(0, "外置兜底:"+e, 0);
    }
}
// 使用外置兜底类
@SentinelResource(value = "getUserById",
        blockHandler = "blockHandlerMethod",
        blockHandlerClass = BlockHandlerClass.class)
public User getUserById(@PathVariable Integer id) {
    return userFeign.getUserById(id);
}

5.2 全局异常处理

统一处理 Sentinel 各类异常,返回标准化响应。

@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 data = null;
        if (e instanceof FlowException) {
            data = new Result(-1, "限流异常");
        } else if (e instanceof DegradeException) {
            data = new Result(-2, "降级异常");
        } else if (e instanceof ParamFlowException) {
            data = new Result(-3, "参数限流异常");
        } else if (e instanceof AuthorityException) {
            data = new Result(-4, "授权异常");
        } else if (e instanceof SystemBlockException) {
            data = new Result(-5, "系统负载异常");
        }
        response.getWriter().write(JSON.toJSONString(data));
    }
}
// 统一返回体
class Result {
    private int status;
    private String msg;
    private Object data;
    // 省略getter/setter/构造器
}

5.3 Sentinel 整合 Feign

实现 Feign 远程调用的熔断降级,避免下游服务异常影响上游。

5.3.1 实现 FallbackFactory

@Component
public class UserFeignFallback implements FallbackFactory<UserFeign> {
    @Override
    public UserFeign create(Throwable t) {
        return new UserFeign() {
            @Override
            public User getUserById(Integer id) {
                return new User(id, "Feign调用失败:"+t, 0);
            }
        };
    }
}

5.3.2 配置 Feign 接口

@FeignClient(value = "sentinel-provider", fallbackFactory = UserFeignFallback.class)
public interface UserFeign {
    @RequestMapping(value = "/provider/getUserById/{id}")
    User getUserById(@PathVariable Integer id);
}

六、总结

Sentinel 凭借轻量、易用、灵活的特性,成为 SpringCloud 微服务架构中服务保护的首选方案。核心要点总结:

  1. 资源定义:通过硬编码 / 注解 / 自动适配(SpringMVC/Feign)定义受保护资源;
  2. 规则配置:控制台 / 代码配置流量控制、熔断降级等规则,按需选择粒度;
  3. 兜底逻辑:通过 blockHandler / 全局异常 / FallbackFactory 处理限流 / 熔断场景;
  4. 核心价值:从流量入口到服务调用全链路保护,防止雪崩效应,保障微服务高可用。

建议结合 JMeter 压测工具验证各类规则效果,加深对 Sentinel 流量控制、熔断降级的理解,根据业务场景灵活配置规则,平衡系统稳定性和可用性。

到此这篇关于SpringCloud Alibaba Sentinel 从入门到精通的文章就介绍到这了,更多相关SpringCloud Alibaba Sentinel 使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文