常德市网站建设_网站建设公司_后端开发_seo优化
2025/12/18 22:22:26 网站建设 项目流程

Sentinel分布式系统的流量防卫兵

在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以通过HTTP/RPC相互调用,在Spring cloud中可以用 RestTemplate + LoadBalanceClientFeign来调用。为保证1其高可用,单个服务通常会集群部署。由于网络原因或自身的原因,服务并不能保证100%可用,如果单个服务出问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,servlet容器的线程资源会被消耗完毕,导致服务瘫痪,服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的 “雪崩” 效应。为了解决这个问题,业界提出了 熔断器模型

一、 基本概念

1.1 流量控制 (Flow Control)

流量控制在网络传输中是一个常用的概念,它用于调整网络包的发送数据。然而从系统稳定性角度考虑,在处理请求的速度上,也有非常多的讲究。任意时间到来的请求往往是随机不可控的,而系统的处理能力是有限的。我们需要根据系统的处理能力对流量进行控制,Sentinel 作为一个调配器,可以根据需要把随机的请求整合成合适的形状。

Sentinel以流量为切入点,从流量控制,熔断降级,系统负载保护,等多个角度维护服务的稳定性。

流量控制有以下几个角度:

  • 资源的调用关系:例如资源的调用链路,资源和资源之间的关系。
  • 运行指标:例如 QPS、线程池、系统负载等。
  • 控制的效果:例如直接限流、冷启动(WarmUp)、排队等。

Sentinel的特征:

  • 丰富的应用场景:
  • Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷(对于突然到来的大量请求,您可以配置流控规则,以稳定的速度逐步处理这些请求,从而避免流量突刺造成系统负载过高)、集群流量控制、实时熔断下游不可用应用等
  • 完备的实时监控: Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况
  • 广泛的开源生态: Sentinel 提供开箱即用的与其它开源框架 / 库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel
  • 完善的 SPI 扩展点: Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等

1.2 熔断降级 (Circuit Breaking)

除了流量控制以外,及时对调用链路中不稳定的因素进行熔断也是 Sentinel 的使命之一。由于调用关系的复杂性,如果调用链路中的某个资源出现了不稳定,可能会导致请求发生堆积,进而导致级联错误。

Sentinel 和 Hystrix 的原则是一致的:当检测到调用链路中某个资源出现不稳定的表现(例如请求响应时间长或异常比例升高)的时候,(对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联故障。

Sentinel 熔断降级设计理念:

  1. 并发线程数限制: 和资源池隔离(Hystrix 采用的方式)不同,Sentinel 通过限制资源并发线程的数量,来减少不稳定资源对其它资源的影响。这样不但没有线程切换的损耗,也不需要预先分配线程池的大小。当某个资源出现不稳定的情况下(如响应时间变长),对资源的直接影响就是会造成线程数的逐步堆积。当线程数在特定资源上堆积到一定的数量之后,对该资源的新请求就会被拒绝。堆积的线程完成任务后才开始继续接收请求。
  2. 响应时间降级: 除了对并发线程数进行控制以外,Sentinel 还可以通过响应时间来快速降级不稳定的资源。当依赖的资源出现响应时间过长后,所有对该资源的访问都会被直接拒绝,直到过了指定的时间窗口之后才重新恢复。

二、 基本使用

2.1 Spring Boot 集成

1. 引入依赖

<!-- Sentinel 核心依赖 -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId><version>2.2.5.RELEASE</version>
</dependency>

2. 定义资源 (@SentinelResource)

@SentinelResource 用于定义资源,并提供可选的异常处理和 fallback 配置项。

属性名 说明与配置规则
value 资源名称,必填项。这是 Sentinel 控制台配置规则时引用的唯一标识。
blockHandler / blockHandlerClass 处理 Sentinel 规则限制触发的异常 (BlockException),如限流、熔断。 1. 修饰符必须是 public。 2. 返回值必须与原方法匹配。 3. 参数必须与原方法匹配,且最后加一个 BlockException 参数。 4. 默认在同一个类中,若使用 blockHandlerClass 指向其他类,则函数必须是 static
fallback / fallbackClass 处理程序运行异常(Java 运行时异常)。 1. 作用范围:针对所有类型的异常(除了 exceptionsToIgnore 中排除的)。 2. 返回值必须与原函数一致。 3. 参数与原函数一致,或者可以额外多一个 Throwable 参数。 4. 若指定 fallbackClass,函数必须为 static
defaultFallback 默认的通用 fallback 逻辑。 1. 参数列表需要为空,或者可以额外多一个 Throwable 参数。 2. 优先级低于 fallback
exceptionsToIgnore 指定哪些异常被排除,不会计入异常统计,也不会进入 fallback 逻辑,原样抛出。

辨析 BlockHandler vs Fallback:

  • BlockHandler: 违反 Sentinel 规则(限流/熔断) -> 捕获 BlockException
  • Fallback: 程序代码抛错(NPE/RunTimeException) -> 捕获 Throwable

代码示例:

@RestController
public class DriverController {@SentinelResource(value = "info", blockHandler = "blockExHandler")@RequestMapping(value = "/info/{id}")public Driver info(@PathVariable(value = "id") String id) throws BlockException {// 模拟业务逻辑if ("0".equals(id)) {throw new RuntimeException("系统异常"); // 会走 fallback(如果配置了的话),或者直接报错}return driverService.findById(id);}/*** info 资源出现 BlockException 后的降级处理*/public Driver blockExHandler(String id, BlockException e) {Driver driver = new Driver();driver.setId(id);driver.setName("系统繁忙, 被 Sentinel限流了, 稍后再试");return driver;}
}

2.2 集成 OpenFeign

1. 开启 Feign 对 Sentinel 的支持

application.yml 中配置:

feign:sentinel:enabled: true

2. 创建 FallbackFactory

推荐使用 FallbackFactory,因为它可以获取到具体的异常信息。

@Component
public class DriverFeignFallbackFactory implements FallbackFactory<DriverFeign> {@Overridepublic DriverFeign create(Throwable throwable) {return new DriverFeign() {@Overridepublic Driver status(String id, Integer status) {Driver driver = new Driver();driver.setId(id);driver.setName("Feign 降级:系统比较繁忙,请您稍后再试!错误信息:" + throwable.getMessage());return driver;}};}
}

3. 在 FeignClient 中指定

@FeignClient(name = "hailtaxi-driver", fallbackFactory = DriverFeignFallbackFactory.class)
public interface DriverFeign {@PutMapping(value = "/driver/status/{id}/{status}")Driver status(@PathVariable(value = "id") String id, @PathVariable(value = "status") Integer status);
}

2.3 集成 Gateway

Sentinel 支持对 Spring Cloud Gateway 网关进行网关流控(针对 Route ID 或 API 分组)。

1. 引入依赖

<!-- Sentinel 适配 Gateway 的依赖 -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<!-- Sentinel 核心 -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

2. 配置自定义异常处理 (BlockRequestHandler)

网关限流默认返回文本,生产环境通常需要返回 JSON。

@Configuration
public class GatewaySentinelConfig {@PostConstructpublic void doInit() {BlockRequestHandler blockRequestHandler = (exchange, t) -> {Map<String, Object> map = new HashMap<>();map.put("code", 429);map.put("message", "网关限流:请求太快,请稍后重试");return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS).contentType(MediaType.APPLICATION_JSON).body(BodyInserters.fromValue(map));};GatewayCallbackManager.setBlockHandler(blockRequestHandler);}
}

3. 初始化规则 (示例)

// 针对路由ID "order_route" 限流
GatewayFlowRule rule = new GatewayFlowRule("order_route").setCount(1).setIntervalSec(1);
GatewayRuleManager.loadRules(Collections.singleton(rule));

三、 规则详解

3.1 流量控制规则

核心属性:

属性 说明
resource 资源名 (唯一标识)。
count 限流阈值。
grade 阈值类型:QPS (1) 或 并发线程数 (0)。
strategy 流控模式:直接、关联、链路。
controlBehavior 流控效果:快速失败、WarmUp (预热)、排队等待 (匀速排队)。

Strategy 流控模式说明:

  • 直接 (Direct): 自身请求达到阈值,直接限流。
  • 关联 (Related): 当关联的资源(RefResource)达到阈值时,限流自己。适用于:支付接口达到阈值,限流下订单接口(优先保证核心业务)。
  • 链路 (Chain): 只记录指定入口(Context)进来的流量。如果从入口 A 进来调用 C 达到阈值则限流,从入口 B 进来调用 C 不限流。

ControlBehavior 流控效果说明:

  • 快速失败: 直接抛出异常。
  • WarmUp: 冷启动。当流量突然激增,让通过的流量在 warmUpPeriodSec 时间内缓慢增加至阈值,防止系统被压垮。
  • 排队等待: 漏桶算法。让请求以均匀的速度通过,多余请求排队,超时则丢弃。

3.2 熔断降级规则

熔断降级基本概念:监控一些请求的异常情况或完成调用的时间,当在单位时间内达到阈值即触发降级

属性 说明
resource 资源名,即规则的作用对象
grade 熔断策略:慢调用比例、异常比例、异常数。
count 阈值(根据 grade 不同而定)。
timeWindow 熔断时长 (秒)。熔断触发后,在此时间内拒绝所有请求。
minRequestAmount 最小请求数(默认5)。只有单位时长内请求数 > 这个值,才会计算比例。
statIntervalMs 统计时长 (ms)。

熔断策略详解:

  1. 慢调用比例 (SLOW_REQUEST_RATIO):
    • 需设置 MaxAllowedRt (最大响应时间)。
    • 若 请求RT > MaxAllowedRt,记为慢调用。
    • 触发条件:请求数 > minRequestAmount 且 慢调用比例 > count
  2. 异常比例 (ERROR_RATIO):
    • 触发条件:请求数 > minRequestAmount 且 异常比例 > count (0.0~1.0)。
  3. 异常数 (ERROR_COUNT):
    • 触发条件:异常数 > count

3.3 系统保护规则

Sentinel 系统自适应限流从整体维度对应用入口流量进行控制,结合应用的Load,CPU使用率、总体平均RT、入口QPS和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性

指标 说明
Load (仅仅 Linux) 当系统 load1 (1分钟负载) > 阈值,且并发线程数 > 系统容量时触发。
RT 单台机器所有入口流量的平均 RT > 阈值。
线程数 单台机器所有入口流量的并发线程数 > 阈值。
入口 QPS 单台机器所有入口流量的 QPS > 阈值。
CPU 使用率 机器 CPU 使用率 > 阈值 (0.0~1.0)。

3.4 访问控制规则

用于实现黑白名单控制。

  1. 前提:获取 Origin (来源)。

    默认 origin 解析为空,需自定义实现RequestOriginParser接口,并注册为 Bean:

    @Component
    public class MyOriginParser implements RequestOriginParser {@Overridepublic String parseOrigin(HttpServletRequest request) {return request.getParameter("source"); // 例如 ?source=appA}
    }
    
  2. 授权规则,即黑白名单规则(AuthorityRule)非常简单,主要是以下配置:

    • resource:资源名,即规则作用对象
    • limitApp:对应黑名单/白名单,不同origin用逗号 分隔,填写来源标识(如 appA)。
    • Strategy: 限制模式,WHITE (白名单,只允许 appA),BLACK (黑名单,拒绝 appA)。

3.5 热点参数规则

针对资源中的特定参数进行限流(例如:针对 ID 为 1 的商品进行限流,ID 为 2 的不限流)。

必须引入额外依赖:

<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-parameter-flow-control</artifactId>
</dependency>

配置说明:

  • 参数索引 (ParamIdx): 第几个参数(0, 1, 2…)。

  • 单机阈值: 默认的限流阈值。

  • 参数例外项 (Exception Items):

    特殊值处理。

    • 例如:参数索引 0,默认阈值 100。
    • 例外项:当参数值为 “vip” 时,阈值设为 500。

四、 安装教程 (Sentinel Dashboard)

Sentinel 控制台用于可视化监控和规则管理。

4.1 服务端安装

  1. 下载
    前往 GitHub Release 下载 sentinel-dashboard-x.x.x.jar

  2. 启动

    使用 Java 命令启动(建议指定端口,避免冲突):

    java -Dserver.port=8858 -jar sentinel-dashboard-1.8.6.jar
    
    • 默认用户名/密码:sentinel / sentinel
  3. 访问
    浏览器打开 http://localhost:8858

4.2 客户端连接配置

在微服务的 application.yml 中添加配置,使其连接到控制台。

spring:application:name: my-app-service  # 必填,用于控制台显示服务名cloud:sentinel:transport:dashboard: localhost:8858  # 控制台地址port: 8719                 # 客户端监控API端口(如果被占用会自动+1)eager: true                  # 饥饿加载,启动时直接向控制台发送心跳(可选)

注意事项:

  1. 懒加载机制: 默认情况下,启动服务后控制台是空的。你需要先请求一次该微服务的接口,触发 Sentinel 初始化,服务才会出现在控制台中。
  2. 规则丢失问题: 默认在控制台配置的规则是保存在内存中的,服务重启后规则会消失。生产环境需要配置 规则持久化(如集成 Nacos)。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询