(第一次刷到本文的小伙伴可移至微服务案例,通过结合案例可以更快理解sentinel)

Sentinel 简介

Sentinel 是阿里巴巴开源的一款面向分布式服务架构的流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来帮助您保障微服务的稳定性。

可以将 Sentinel 看作是微服务架构中的"流量哨兵",它能够实时监控服务的运行状态,并根据预设规则对流量进行控制,防止系统因突发流量或服务异常而崩溃。

为什么使用 Sentinel?

想象一下,当一个大型商场在举办大型促销活动时,如果人流过大,可能会导致商场内拥挤不堪,甚至引发安全事故。这时商场通常会采取限流措施,比如在入口处控制进入人数,或者在某些热门店铺前设置排队机制。

Sentinel 就像这个商场的"安全管理员",它能够:

  1. 流量控制:控制进入系统的请求量,防止系统过载
  2. 熔断降级:当下游服务出现故障时,及时熔断,避免故障扩散
  3. 系统保护:根据系统实时负载情况,自动调整流量策略

Sentinel 核心功能

1. 流量控制(Flow Control)

Sentinel 可以根据不同的维度对流量进行控制,包括:

  • QPS(每秒查询数)控制
  • 线程数控制
  • 调用关系控制
  • 热点参数控制

这里就不逐一演示了,可以自行设置去玩一下

当流量超过设定阈值时,Sentinel 会按照预设策略对请求进行处理,如直接拒绝、排队等待等。

2. 熔断降级(Circuit Breaker)

当某个服务出现异常(如响应时间过长、异常比例过高)时,Sentinel 会自动触发熔断机制,暂时停止对该服务的调用,避免故障扩散。在一段时间后,Sentinel 会尝试半开状态,逐步恢复服务调用。

熔断器有三种状态:

  • Closed(关闭状态):正常处理请求
  • Open(打开状态):所有请求被熔断,直接返回降级处理
  • Half-Open(半开状态):允许部分请求通过,检测服务是否恢复正常

这里用慢调用比例为例,剩下的异常比例与异常数大同小异

热点和授权这里不过多讲解,感兴趣的朋友可以自行了解

3. 系统自适应保护

Sentinel 能够根据系统的实时负载情况(如CPU使用率、系统负载等)自动调整流量控制策略,保护系统不被压垮。

4. 实时监控

Sentinel 提供了强大的实时监控功能,可以通过控制台查看应用的实时流量数据,包括QPS、响应时间、异常数等指标。

Sentinel 在项目中的配置

从项目代码中可以看出,Sentinel 的配置主要分为以下几个部分:

1. Maven 依赖配置

shop-order-server/pom.xml 文件中添加了 Sentinel 相关依赖:

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

以及在 shop-api-gateway/pom.xml 中:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
2. Sentinel 控制台配置

shop-order-server/src/main/resources/application.yml 中配置了 Sentinel 控制台:

cloud:
  sentinel:
    transport:
      dashboard: localhost:8080  # Sentinel 控制台地址
      port: 9898                 # 客户端端口
3. Nacos 规则配置

shop-order-server/src/main/resources/bootstrap.yml 中配置了从 Nacos 读取流控规则:

sentinel:
  datasource:
    ds1:
      nacos:
        server-addr: localhost:8848
        data-id: sentinel-consumer-ds1
        group-id: DEFAULT_GROUP
        data-type: json
        rule-type: flow

这表示从 Nacos 中读取 data-id 为 sentinel-consumer-ds1 的配置作为流控规则。

4. 自定义异常处理器

在项目中实现了自定义的 BlockExceptionHandler:

@Component
public class ShopBlockExceptionHandler implements BlockExceptionHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
        Map<String, Object> map = new HashMap<>();
        if (e instanceof FlowException){
            // 限流异常
            map.put("code",-1);
            map.put("msg","限流异常");
        } else if (e instanceof DegradeException) {
            // 降级异常
            map.put("code",-2);
            map.put("msg","降级异常");
        } else if (e instanceof ParamFlowException) {
            // 热点异常
            map.put("code",-3);
            map.put("msg","热点异常");
        } else if (e instanceof AuthorityException) {
            // 授权异常
            map.put("code",-4);
            map.put("msg","限授权异常");
        } else if (e instanceof SystemBlockException) {
            // 系统异常
            map.put("code",-5);
            map.put("msg","系统异常");
        }
        String jsonString = JSON.toJSONString(map);
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().write(jsonString);
    }
}
5. 网关限流配置

在网关项目中配置了限流处理:

@Configuration
public class ShopGatewayConfig {
    @PostConstruct
    public void ShopGratewayExceptionHandler() {
        BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
            @Override
            public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
                Map<String,Object> map = new HashMap<>();
                map.put("code",-100);
                map.put("message","网关路由被限流");
                return ServerResponse.status(HttpStatus.OK)
                        .contentType(MediaType.APPLICATION_JSON)
                        .body(BodyInserters.fromValue(map));
            }
        };
        GatewayCallbackManager.setBlockHandler(blockRequestHandler);
    }
}
6. 使用 @SentinelResource 注解

在代码中通过 @SentinelResource 注解定义资源

@SentinelResource("product")
@RequestMapping("/product")
public String product(Long pid){
    return "商品:" + pid;
}

测试接口说明        

从项目中的 SentinelController 可以看出,提供了多个用于测试的接口:

  • http://localhost:8091/sentinel1?token=12 - 测试基本的限流功能
  • http://localhost:8091/sentinel2?token=12 - 测试高并发场景
  • http://localhost:8091/vip?token=12 - 测试 vip 资源的限流
  • http://localhost:8091/comm?token=12 - 测试 comm 资源的限流
  • http://localhost:8091/trace1?token=12 - 测试链路限流
  • http://localhost:8091/trace2?token=12 - 测试链路限流
  • http://localhost:8091/trace3?token=12 - 测试链路限流
  • http://localhost:8091/fallBack2?token=12 - 测试熔断降级(模拟33%的异常率)
  • http://localhost:8091/product?token=12 - 测试 @SentinelResource 注解
  • http://localhost:8091/authority?token=12 - 测试授权规则

测试方法

1. 启动 Sentinel 控制台

  • 下载并启动 Sentinel Dashboard
  • 访问 http://localhost:8080 登录控制台

2. 启动项目

  • 启动 Nacos 服务
  • 启动网关、订单、商品、用户等服务

3. 配置规则

  • 在 Sentinel 控制台中为不同资源配置流控规则、降级规则等
  • 也可以通过 Nacos 配置规则,实现规则的持久化

4. 发起请求测试

  • 使用工具(如 Postman、JMeter)向测试接口发送请求
  • 观察 Sentinel 控制台的实时监控数据
  • 验证限流、熔断等规则是否生效

5. 验证异常处理

  • 当触发限流、熔断等规则时,检查自定义异常处理器是否正确返回相应结果

通过以上配置和测试,可以确保微服务系统在高并发场景下的稳定性和可靠性。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐